Skip to content

Commit 238e790

Browse files
committed
remove conncectivy matrix, and use cellnodes!(dh) instead
1 parent 1e1d761 commit 238e790

8 files changed

+69
-81
lines changed

examples/enf_2d.jl

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@ IgAShell.IGAShellData(;
8686
igashell =
8787
IgAShell.IGAShell(
8888
cellset = partset1,
89-
connectivity = nurbsmesh.IEN,#reverse(nurbsmesh.IEN, dims=1),
9089
data = igashelldata
9190
)
9291
push!(data.parts, igashell)

src/igashell_adaptivity.jl

+33-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ struct IGAShellAdaptivity{T}
88
cellstates::Vector{CELLSTATE}
99
control_point_states::Vector{CPSTATE}
1010
propagation_checked::Matrix{Bool}
11+
locked_elements::Vector{Int}
1112
locked_control_points::Vector{Int}
1213

1314
lumped2layered::IGA.BezierExtractionOperator{T}
@@ -32,7 +33,6 @@ function get_controlpoint_state(adap::IGAShellAdaptivity, cpid::Vector{Int})
3233
return adap.control_point_states[cpid]
3334
end
3435

35-
3636
function set_controlpoint_state!(adap::IGAShellAdaptivity, cpid::Int, state::CPSTATE)
3737
adap.control_point_states[cpid] = state
3838
end
@@ -41,7 +41,7 @@ function setcellstate!(adap::IGAShellAdaptivity, cellid::Int, state::CELLSTATE)
4141
adap.cellstates[cellid] = state
4242
end
4343

44-
function IGAShellAdaptivity(data::IGAShellData{dim_p,dim_s,T}, cell_connectivity::Matrix{Int}, ncells, nnodes) where {dim_p,dim_s,T}
44+
function IGAShellAdaptivity(data::IGAShellData{dim_p,dim_s,T}, ncells) where {dim_p,dim_s,T}
4545

4646
order = data.orders[dim_s]
4747
ninterfaces = data.nlayers-1
@@ -66,49 +66,58 @@ function IGAShellAdaptivity(data::IGAShellData{dim_p,dim_s,T}, cell_connectivity
6666
Cla2di = IGA.bezier_extraction_to_vector(Cmat_la2di')
6767
Clu2di = IGA.bezier_extraction_to_vector(Cmat_lu2di')
6868

69+
propagation_checked = [false for _ in 1:ninterfaces, _ in 1:ncells]
70+
71+
node_states = CPSTATE[] #initialized later in _init_cpstates_cellstates
72+
locked_control_points = Int[]
73+
74+
return IGAShellAdaptivity(data.initial_cellstates, node_states, propagation_checked, data.locked_elements, locked_control_points,
75+
Clu2la, Cla2di, Clu2di,
76+
weakdiscont2discont, strongdiscont2discont,
77+
interface_knots, order)
78+
end
79+
80+
function _init_cpstates_cellstates!(dh::Ferrite.AbstractDofHandler, igashell)
81+
82+
nnodes = get_n_controlpoints(igashell.layerdata)
83+
cellnodes = igashell.cache.cellnodes
84+
6985
#Some of the cells will be initialized with LUMPED, and some with LYARED/DISCONTINIUOS
7086
# This means that some cells will be in a mixed mode... Determine those
7187
# Prioritize the DISCONTINIUOS before LAYERED and LUMPED, ie. if one node is both lumped
7288
# and disocontinous, choose it to be dinscontionous
7389
node_states = fill(LUMPED_CPSTATE, nnodes)
7490

75-
for cellid in 1:ncells
76-
cellstate = data.initial_cellstates[cellid]
77-
for cellnodes in cell_connectivity[:, cellid]
78-
for nodeid in cellnodes
79-
node_states[nodeid] = combine_states(node_states[nodeid], first(cellstate.cpstates), ninterfaces)
80-
end
91+
for cellid in 1:getncells(igashell)
92+
cellstate = igashell.adaptivity.cellstates[cellid]
93+
Ferrite.cellnodes!(cellnodes, dh, cellid)
94+
for nodeid in cellnodes
95+
node_states[nodeid] = combine_states(node_states[nodeid], first(cellstate.cpstates), ninterfaces(igashell))
8196
end
97+
8298
end
8399

84100
#Check if there is any cell that is has MIXED states controlpoints
85-
for cellid in 1:ncells
86-
nodeids = cell_connectivity[:, cellid]
87-
cellnode_states = node_states[nodeids]
101+
for cellid in 1:getncells(igashell)
102+
Ferrite.cellnodes!(cellnodes, dh, cellid)
103+
cellnode_states = node_states[cellnodes]
88104

89105
#if NOT all of the nodes in the cell are equal, the element is mixed
90106
if !all(first(cellnode_states) .== cellnode_states)
91-
data.initial_cellstates[cellid] = CELLSTATE(_MIXED, copy(cellnode_states))
107+
igashell.adaptivity.cellstates[cellid] = CELLSTATE(_MIXED, copy(cellnode_states))
92108
end
93109

94110
end
95-
96-
propagation_checked = [false for _ in 1:ninterfaces, _ in 1:ncells]
97111

98112
#Some cells are not allowed to be upgraded (locked).. store the contorl points of these cells
99-
locked_control_points = Int[]
100-
for cellid in data.locked_elements
101-
for cell_nodes in cell_connectivity[:, cellid]
102-
for nodeid in cell_nodes
103-
push!(locked_control_points, nodeid)
104-
end
113+
for cellid in igashell.adaptivity.locked_elements
114+
Ferrite.cellnodes!(cellnodes, dh, cellid)
115+
for nodeid in cellnodes
116+
push!(igashell.adaptivity.locked_control_points, nodeid)
105117
end
106118
end
107119

108-
return IGAShellAdaptivity(data.initial_cellstates, node_states, propagation_checked, locked_control_points,
109-
Clu2la, Cla2di, Clu2di,
110-
weakdiscont2discont, strongdiscont2discont,
111-
interface_knots, order)
120+
Ferrite.copy!!(igashell.adaptivity.control_point_states, node_states)
112121
end
113122

114123
function get_upgrade_operator(adap::IGAShellAdaptivity, from::CPSTATE, to::CPSTATE)

src/igashell_data.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,5 @@ getwidth(data::IGAShellData) = data.width
417417

418418
LIMIT_STRESS_CRITERION(data::IGAShellData) = data.limit_stress_criterion
419419
LIMIT_DAMAGE_VARIABLE(data::IGAShellData) = data.limit_damage_criterion
420-
PROPAGATION_SEARCH_RADIUS(data::IGAShellData) = data.search_radius
420+
PROPAGATION_SEARCH_RADIUS(data::IGAShellData) = data.search_radius
421+
get_n_controlpoints(data::IGAShellData{dim_p}) where {dim_p} = prod( (i) -> length(data.knot_vectors[i]) - data.orders[i] - 1, 1:dim_p)

src/igashell_main.jl

+17-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
export IGAShellState, IGAShell
22

3+
struct IGAShellCache
4+
cellnodes::Vector{Int}
5+
#celldofs::Vector{Int}
6+
#cellcoords::Vector{Vec{dim,T}}
7+
end
8+
9+
IGAShellCache(data::IGAShellData) = IGAShellCache(zeros(Int, Ferrite.nnodes_per_cell(data)))
10+
311
"""
412
IGAShell
513
@@ -10,16 +18,17 @@ struct IGAShell{dim_p, dim_s, T,
1018
intdata<:IGAShellIntegrationData,
1119
adapdata<:IGAShellAdaptivity,
1220
vtkdata<:IGAShellVTK,
13-
srdata<:IGAShellStressRecovory} <: Five.AbstractPart{dim_s}
21+
srdata<:IGAShellStressRecovory,
22+
cache<:IGAShellCache} <: Five.AbstractPart{dim_s}
1423

1524
layerdata::data
1625
integration_data::intdata
1726
adaptivity::adapdata
1827
vtkdata::vtkdata
1928
stress_recovory::srdata
29+
cache::cache
2030

2131
cellset::Vector{Int}
22-
cell_connectivity::Matrix{Int}
2332
end
2433

2534
#Utility functions
@@ -29,9 +38,6 @@ intdata(igashell::IGAShell) = igashell.integration_data
2938
vtkdata(igashell::IGAShell) = igashell.vtkdata
3039
srdata(igashell::IGAShell) = igashell.stress_recovory
3140

32-
cellconectivity!(nodes::Vector{Int}, igashell::IGAShell, cellid::Int) = nodes .= igashell.cell_connectivity[:, cellid]
33-
cellconectivity(igashell::IGAShell, cellid::Int) = @view igashell.cell_connectivity[:, cellid]
34-
3541
Ferrite.getnquadpoints(igashell::IGAShell) = getnquadpoints_per_layer(igashell)*nlayers(igashell)
3642
getnquadpoints_inplane(igashell::IGAShell) = length(getweights(intdata(igashell).iqr))
3743
getnquadpoints_ooplane(igashell::IGAShell) = length(getweights(intdata(igashell).oqr))
@@ -61,7 +67,6 @@ getcellstate(igashell::IGAShell, i::Int) = igashell.adaptivity.cellstates[i]
6167
Ferrite.nnodes_per_cell(igashell::IGAShell{dim_p}, cellid::Int=1) where dim_p = prod(igashell.layerdata.orders[1:dim_p].+1)::Int#getnbasefunctions(igashell.cv_inplane) ÷ dim_p
6268
Ferrite.getdim(igashell::IGAShell{dim_p,dim_s}) where {dim_p,dim_s} = dim_s
6369
Ferrite.getncells(igashell::IGAShell) = length(igashell.cellset)
64-
Ferrite.getnnodes(igashell::IGAShell) = maximum(igashell.cell_connectivity)
6570

6671
Five.get_fields(igashell::IGAShell) = [Field(:u, getmidsurface_ip(layerdata(igashell)), ndofs_per_controlpoint(igashell, LUMPED_CPSTATE))]
6772

@@ -74,7 +79,7 @@ function get_inplane_qp_range(n_qp_per_layer::Int, n_inpqp::Int, ilayer::Int, ro
7479
return (1:n_inpqp) .+ offset
7580
end
7681

77-
function _igashell_input_checks(data::IGAShellData{dim_p, dim_s}, cellset::AbstractVector{Int}, cell_connectivity::Matrix{Int}) where {dim_s,dim_p}
82+
function _igashell_input_checks(data::IGAShellData{dim_p, dim_s}, cellset::AbstractVector{Int}) where {dim_s,dim_p}
7883

7984
@assert(!any(is_mixed.(data.initial_cellstates)))
8085
@assert( dim_s == length(data.orders) )
@@ -83,17 +88,15 @@ end
8388

8489
function IGAShell(;
8590
cellset::AbstractVector{Int},
86-
connectivity::Matrix{Int},
8791
data::IGAShellData{dim_p,dim_s,T}
8892
) where {dim_p,dim_s,T}
8993

90-
_igashell_input_checks(data, cellset, connectivity)
94+
_igashell_input_checks(data, cellset)
9195

9296
ncells = length(cellset)
93-
ncontrol_points = maximum(connectivity)
9497

9598
#Setup adaptivity structure
96-
adapdata = IGAShellAdaptivity(data, connectivity, ncells, ncontrol_points)
99+
adapdata = IGAShellAdaptivity(data, ncells)
97100

98101
#
99102
Ce_mat, _ = IGA.compute_bezier_extraction_operators(data.orders[1:dim_p], data.knot_vectors[1:dim_p])
@@ -103,13 +106,15 @@ function IGAShell(;
103106
vtkdata = IGAShellVTK(data)
104107
intdata = IGAShellIntegrationData(data, Ce_vec)
105108
srdata = IGAShellStressRecovory(data)
109+
cache = IGAShellCache(data)
106110

107-
return IGAShell{dim_p,dim_s,T, typeof(data), typeof(intdata), typeof(adapdata), typeof(vtkdata), typeof(srdata)}(data, intdata, adapdata, vtkdata, srdata, cellset, connectivity)
111+
return IGAShell{dim_p,dim_s,T, typeof(data), typeof(intdata), typeof(adapdata), typeof(vtkdata), typeof(srdata), typeof(cache)}(data, intdata, adapdata, vtkdata, srdata, cache, cellset)
108112

109113
end
110114

111115
function Five.init_part!(igashell::IGAShell, dh::Ferrite.AbstractDofHandler)
112116
_init_vtk_grid!(dh, igashell)
117+
_init_cpstates_cellstates!(dh, igashell)
113118
end
114119

115120
struct IGAShellState{MS1<:Five.AbstractMaterialState,MS2<:Five.AbstractMaterialState} <: Five.AbstractPartState

src/igashell_upgrade.jl

+7-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ function _commit_part!(dh::Ferrite.AbstractDofHandler,
55

66
instructions = FieldDimUpgradeInstruction[]
77
upgraded_cells = Int[]
8-
8+
cellnodes = zeros(Int, Ferrite.nnodes_per_cell(igashell))
99
#copy of the current node states
1010
node_states = deepcopy(adapdata(igashell).control_point_states)
1111

@@ -61,7 +61,8 @@ function _commit_part!(dh::Ferrite.AbstractDofHandler,
6161

6262
# Loop through all nodes for this cell and set the state
6363
# of the node to the state of the cell, if it is an "upgrade"
64-
for (i, nodeid) in enumerate(igashell.cell_connectivity[:, ic])
64+
Ferrite.cellnodes!(cellnodes, dh, cellid)
65+
for (i, nodeid) in enumerate(cellnodes)
6566
node_states[nodeid] = combine_states(node_states[nodeid], get_cpstate(upgrade_to, i), ninterfaces(igashell))
6667
end
6768
end
@@ -76,7 +77,7 @@ function _commit_part!(dh::Ferrite.AbstractDofHandler,
7677
ue = state.d[_celldofs]
7778
Δue = state.Δd[_celldofs]
7879

79-
cellnodes = igashell.cell_connectivity[:, ic]
80+
Ferrite.cellnodes!(cellnodes, dh, cellid)
8081
new_cellnode_states = node_states[cellnodes]
8182
current_cellnode_states = igashell.adaptivity.control_point_states[cellnodes]
8283

@@ -86,7 +87,7 @@ function _commit_part!(dh::Ferrite.AbstractDofHandler,
8687
continue
8788
end
8889

89-
instr = construct_upgrade_instruction(igashell, cellid, current_cellnode_states, new_cellnode_states, ue, Δue)
90+
instr = construct_upgrade_instruction(igashell, cellid, cellnodes, current_cellnode_states, new_cellnode_states, ue, Δue)
9091
push!(instructions, instr)
9192

9293
# Check if the element is mixed.
@@ -236,7 +237,7 @@ function stress_interface_index(qplayerid::Int, nqpinplane::Int, dim_p::Int)
236237
return idx
237238
end
238239

239-
function construct_upgrade_instruction(igashell::IGAShell{dim_p,dim_s,T}, cellid::Int, current_cellnode_state::AbstractVector{CPSTATE}, cellnode_states::AbstractVector{CPSTATE}, ue::Vector{T}, Δue::Vector{T}) where {dim_p,dim_s,T}
240+
function construct_upgrade_instruction(igashell::IGAShell{dim_p,dim_s,T}, cellid::Int, cellnodes::Vector{Int}, current_cellnode_state::AbstractVector{CPSTATE}, cellnode_states::AbstractVector{CPSTATE}, ue::Vector{T}, Δue::Vector{T}) where {dim_p,dim_s,T}
240241

241242
local_dof_idxs = Int[]
242243
current_fielddims = Int[]
@@ -250,7 +251,7 @@ function construct_upgrade_instruction(igashell::IGAShell{dim_p,dim_s,T}, cellid
250251
# Loop through all node in the cell and create the "instructions" that the
251252
# dofhandler needs in order to distribute new dofs.
252253

253-
for (i, nodeid) in enumerate(igashell.cell_connectivity[:,cellid])
254+
for (i, nodeid) in enumerate(cellnodes)
254255

255256
cp_state = current_cellnode_state[i]
256257
current_fielddim = ndofs_per_controlpoint(igashell, cp_state)

src/igashell_utils.jl

+3-30
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,19 @@ end
3737
function initial_upgrade_of_dofhandler(dh::MixedDofHandler, igashell::IGAShell)
3838

3939
instructions = Five.FieldDimUpgradeInstruction[]
40+
cellnodes = igashell.cache.cellnodes
4041

4142
for (ic, cellid) in enumerate(igashell.cellset)
4243

43-
cellnodes = igashell.cell_connectivity[:, ic]
44+
Ferrite.cellnodes!(cellnodes, dh, cellid)
4445
cellnode_states = adapdata(igashell).control_point_states[cellnodes]
4546

4647
initial_cellnode_states = fill(LUMPED_CPSTATE, length(cellnode_states))
4748

4849
if cellnode_states != initial_cellnode_states
4950
ndofs = ndofs_per_cell(dh, cellid)
5051

51-
instr = construct_upgrade_instruction(igashell, cellid, initial_cellnode_states, cellnode_states, zeros(Float64, ndofs), zeros(Float64, ndofs))
52+
instr = construct_upgrade_instruction(igashell, cellid, cellnodes, initial_cellnode_states, cellnode_states, zeros(Float64, ndofs), zeros(Float64, ndofs))
5253
push!(instructions, instr)
5354
end
5455

@@ -135,34 +136,6 @@ function active_basefunctions(field_dim::Int, ::Int)
135136
return 1:field_dim
136137
end
137138

138-
139-
#igashelldofs(dh::Ferrite.AbstractDofHandler, igashell::IGAShell, index::GeometryObject) = celldofs(dh, index[1])[igashelldofs(igashell, index)]
140-
141-
function igashelldofs(igashell::IGAShell{dim_p,dim_s}, index::GeometryObject, components::Vector{Int}=collect(1:dim_s)) where {dim_p,dim_s}
142-
143-
cellid = index[1]
144-
ip = getmidsurface_ip(layerdata(igashell))
145-
146-
facepoints = geometryobject(ip, index)
147-
148-
face_dofs = Int[]; currentdof = 1
149-
for (i, nodeid) in enumerate(cellconectivity(igashell, cellid))
150-
nodestate = get_controlpoint_state(adapdata(igashell), nodeid)
151-
nnodes_per_controlpoints = ndofs_per_controlpoint(igashell, nodestate) ÷ dim_s
152-
if i in facepoints
153-
for basefunc in active_basefunctions(nnodes_per_controlpoints, index)
154-
for d in components
155-
push!(face_dofs, currentdof + (basefunc-1)*dim_s + d -1)
156-
end
157-
end
158-
end
159-
currentdof += nnodes_per_controlpoints*dim_s
160-
end
161-
162-
return face_dofs
163-
end
164-
165-
166139
function extrapolate(y1,y2,x1,x2,x)
167140
return y1 + ((x-x1)/(x2-x1))*(y2-y1)
168141
end#

src/igashell_vtk.jl

+7-5
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ function Five.get_vtk_displacements(dh::Ferrite.AbstractDofHandler, igashell::IG
162162
ue = state.d[celldofs]
163163

164164
#Transform displayements to fully discontinuous state
165-
cellconectivity!(nodes, igashell, ic)
165+
Ferrite.cellnodes!(nodes, dh, ic)
166166
ue_bezier = T[]
167167
offset = 1
168168

@@ -211,14 +211,16 @@ function Five.get_vtk_celldata(igashell::IGAShell{dim_p,dim_s,T}, output::VTKCel
211211
end
212212

213213
cellstates = zeros(Int, nvtkcells)
214+
cellnodes = zeros(Int, Ferrite.nnodes_per_cell(igashell))
215+
214216
for (ic, cellid) in enumerate(igashell.cellset)
215217
cellstate = getcellstate(adapdata(igashell), ic)
216218
for ilay in 1:nlayers(igashell)
217219
for vtkcell in nvtkcells_per_layer(vtkdata(igashell))
218-
cellnodes = zeros(Int, Ferrite.nnodes_per_cell(igashell, ic))
219-
cellconectivity = cellconectivity!(cellnodes, igashell, ic)
220-
tmp_cellstate = get_controlpoint_state(adapdata(igashell), cellconectivity[1])
221-
for (i, nodeid) in enumerate(cellconectivity[2:end])
220+
221+
Ferrite.cellnodes!(cellnodes, globaldata.dh, ic)
222+
tmp_cellstate = get_controlpoint_state(adapdata(igashell), cellnodes[1])
223+
for (i, nodeid) in enumerate(cellnodes[2:end])
222224
cp_state = get_controlpoint_state(adapdata(igashell), nodeid)
223225
tmp_cellstate = tmp_cellstate.state > cp_state.state ? tmp_cellstate : cp_state
224226
end

test/igashell_test.jl

-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ function get_curved_mesh(cellstate; h, b, R)
9999

100100
igashell = IgAShell.IGAShell(
101101
cellset = collect(1:getncells(grid)),
102-
connectivity = reverse(nurbsmesh.IEN, dims=1),
103102
data = igashelldata)
104103

105104
return grid, igashell
@@ -195,7 +194,6 @@ function get_test_mesh(CELLSTATE::IgAShell.CELLSTATE, nelx, damage)
195194
igashell =
196195
IgAShell.IGAShell(
197196
cellset = 1:nelx,
198-
connectivity = reverse(nurbsmesh.IEN, dims=1),
199197
data = igashelldata
200198
)
201199
push!(data.parts, igashell)

0 commit comments

Comments
 (0)