Skip to content

Commit 5d5ccf0

Browse files
authored
Merge pull request #234 from kaipartmann/bc_handling
Introducing a boundary condition handler
2 parents ead73d8 + 2920a25 commit 5d5ccf0

20 files changed

+1549
-242
lines changed

docs/src/private_api_reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Peridynamics.find_points
2323
Peridynamics.apply_precracks!
2424
Peridynamics.apply_precrack!
2525
Peridynamics.point_sets_intersect
26+
Peridynamics.displacement_bc!
2627
Peridynamics.velocity_databc!
2728
Peridynamics.forcedensity_databc!
2829
Peridynamics.invreg
@@ -48,6 +49,7 @@ Peridynamics.InteractionSystem
4849
Peridynamics.PointSetsPreCrack
4950
Peridynamics.StandardPointParameters
5051
Peridynamics.SingleDimBC
52+
Peridynamics.PosSingleDimBC
5153
Peridynamics.PosDepSingleDimBC
5254
Peridynamics.CKIPointParameters
5355
Peridynamics.BACPointParameters

src/Peridynamics.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ include("discretization/bond_system_corrections.jl")
116116
include("discretization/zem_stabilization.jl")
117117
include("discretization/bond_associated_system.jl")
118118
include("discretization/interaction_system.jl")
119+
include("discretization/condition_handler.jl")
119120
include("discretization/body_chunk.jl")
120121

121122
include("core/job.jl")

src/auxiliary/io.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,5 +167,5 @@ function export_fields!(vtk, chunk, fields_spec::Dict{Symbol,Vector{Symbol}})
167167
end
168168

169169
@inline function get_loc_position(chunk::AbstractBodyChunk)
170-
return @views chunk.storage.position[:, 1:n_loc_points(chunk)]
170+
return @views chunk.storage.position[:, 1:get_n_loc_points(chunk)]
171171
end

src/core/systems.jl

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ end
1616
return get_n_loc_points(system.chunk_handler)
1717
end
1818

19+
@inline function get_n_points(system::AbstractSystem)
20+
return get_n_points(system.chunk_handler)
21+
end
22+
1923
@inline function get_point_ids(system::AbstractSystem)
2024
return get_point_ids(system.chunk_handler)
2125
end
@@ -48,10 +52,78 @@ end
4852
return get_loc_view(a, system.chunk_handler)
4953
end
5054

51-
@inline function get_n_points(system::AbstractSystem)
52-
return get_n_points(system.chunk_handler)
55+
@inline function get_n_dim(::AbstractSystem)
56+
return 3 # 3D only for now
57+
end
58+
59+
@inline function get_n_dof(system::AbstractSystem)
60+
return get_n_dim(system) * get_n_points(system)
61+
end
62+
63+
@inline function get_n_loc_dof(system::AbstractSystem)
64+
return get_n_dim(system) * get_n_loc_points(system)
65+
end
66+
67+
@inline function each_dim(system::AbstractSystem)
68+
return 1:get_n_dim(system)
69+
end
70+
71+
@inline function get_dof(system::AbstractSystem, dim::Int, point_id::Int)
72+
return get_dof(get_n_dim(system), dim, point_id)
73+
end
74+
75+
@inline function get_dof(n_dim::Int, dim::Int, point_id::Int)
76+
return (point_id - 1) * n_dim + dim
77+
end
78+
79+
@inline function each_dof_idx(system::AbstractSystem)
80+
return each_dof_idx(get_n_dim(system), 1:get_n_points(system))
81+
end
82+
83+
@inline function each_loc_dof_idx(system::AbstractSystem)
84+
return each_dof_idx(get_n_dim(system), 1:get_n_loc_points(system))
85+
end
86+
87+
@inline function each_dof_idx(system::AbstractSystem, idxs::AbstractVector{<:Integer})
88+
return each_dof_idx(get_n_dim(system), idxs)
89+
end
90+
91+
#=
92+
This function generates a cartesian product of dof indices, dimensions, and point indices.
93+
In Julia it is very convenient, because elements in a 2-dimensional array can be
94+
accessed via:
95+
A[dof]
96+
or via
97+
A[dim, i]
98+
=#
99+
@inline function each_dof_idx(n_dim::Int, idxs::AbstractVector{<:Integer})
100+
return ((get_dof(n_dim, dim, i), dim, i) for i in idxs, dim in 1:n_dim)
101+
end
102+
103+
@inline function each_dof(system::AbstractSystem)
104+
return each_dof(get_n_dim(system), 1:get_n_points(system))
53105
end
54106

107+
@inline function each_loc_dof(system::AbstractSystem)
108+
return each_dof(get_n_dim(system), 1:get_n_loc_points(system))
109+
end
110+
111+
@inline function each_dof(system::AbstractSystem, idxs::AbstractVector{<:Integer})
112+
return each_dof(get_n_dim(system), idxs)
113+
end
114+
115+
@inline function each_dof(n_dim::Int, idxs::AbstractVector{<:Integer})
116+
return (get_dof(n_dim, dim, i) for i in idxs, dim in 1:n_dim)
117+
end
118+
119+
# Get the point index from a dof index.
120+
get_point(system::AbstractSystem, idx::Int) = get_point(get_n_dim(system), idx)
121+
get_point(n_dim::Int, idx::Int) = div(idx - 1, n_dim) + 1
122+
123+
# Get the dimension index from a dof index.
124+
get_dim(system::AbstractSystem, idx::Int) = get_dim(get_n_dim(system), idx)
125+
get_dim(n_dim::Int, idx::Int) = mod(idx - 1, n_dim) + 1
126+
55127
@inline function init_field_system(system, field)
56128
return nothing
57129
end

src/discretization/body.jl

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ struct Body{M<:AbstractMaterial,P<:AbstractPointParameters} <: AbstractBody{M}
9191
params_map::Vector{Int}
9292
single_dim_bcs::Vector{SingleDimBC}
9393
posdep_single_dim_bcs::Vector{PosDepSingleDimBC}
94+
pos_single_dim_bcs::Vector{PosSingleDimBC}
95+
data_bcs::Vector{DataBC}
9496
single_dim_ics::Vector{SingleDimIC}
9597
posdep_single_dim_ics::Vector{PosDepSingleDimIC}
96-
data_bcs::Vector{DataBC}
9798
point_sets_precracks::Vector{PointSetsPreCrack}
9899

99100
function Body(mat::M, position::AbstractMatrix, volume::AbstractVector) where {M}
@@ -109,14 +110,16 @@ struct Body{M<:AbstractMaterial,P<:AbstractPointParameters} <: AbstractBody{M}
109110

110111
single_dim_bcs = Vector{SingleDimBC}()
111112
posdep_single_dim_bcs = Vector{PosDepSingleDimBC}()
113+
pos_single_dim_bcs = Vector{PosSingleDimBC}()
112114
single_dim_ics = Vector{SingleDimIC}()
113115
posdep_single_dim_ics = Vector{PosDepSingleDimIC}()
114-
v_bcs = Vector{DataBC}()
116+
data_bcs = Vector{DataBC}()
115117
point_sets_precracks = Vector{PointSetsPreCrack}()
116118

117119
new{M,P}(name, mat, n_points, position, volume, fail_permit, point_sets,
118-
point_params, params_map, single_dim_bcs, posdep_single_dim_bcs, v_bcs,
119-
single_dim_ics, posdep_single_dim_ics, point_sets_precracks)
120+
point_params, params_map, single_dim_bcs, posdep_single_dim_bcs,
121+
pos_single_dim_bcs, data_bcs, single_dim_ics, posdep_single_dim_ics,
122+
point_sets_precracks)
120123
end
121124
end
122125

@@ -163,6 +166,10 @@ function Base.show(io::IO, ::MIME"text/plain", @nospecialize(body::AbstractBody)
163166
print(io, "\n ")
164167
show(io, bc)
165168
end
169+
for bc in body.pos_single_dim_bcs
170+
print(io, "\n ")
171+
show(io, bc)
172+
end
166173
for bc in body.data_bcs
167174
print(io, "\n ")
168175
show(io, bc)
@@ -319,6 +326,11 @@ function log_msg_body(body::AbstractBody)
319326
settings = @sprintf("set `%s`, dimension %d", bc.point_set, bc.dim)
320327
msg *= msg_qty(descr, settings; indentation=4)
321328
end
329+
for bc in body.pos_single_dim_bcs
330+
descr = @sprintf("%s condition", field_to_name(bc.field))
331+
settings = @sprintf("set `%s`, dimension %d", bc.point_set, bc.dim)
332+
msg *= msg_qty(descr, settings; indentation=4)
333+
end
322334
msg *= " MATERIAL\n"
323335
msg *= log_material(body.mat; indentation=4)
324336
n_point_params = length(body.point_params)
@@ -372,8 +384,9 @@ end
372384
@inline function n_bcs(body::AbstractBody)
373385
n_sdbcs = length(body.single_dim_bcs)
374386
n_pdsdbcs = length(body.posdep_single_dim_bcs)
387+
n_psdbcs = length(body.pos_single_dim_bcs)
375388
n_databcs = length(body.data_bcs)
376-
return n_sdbcs + n_pdsdbcs + n_databcs
389+
return n_sdbcs + n_pdsdbcs + n_psdbcs + n_databcs
377390
end
378391
@inline function n_ics(body::AbstractBody)
379392
n_sdics = length(body.single_dim_ics)

src/discretization/body_chunk.jl

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,7 @@ struct BodyChunk{System<:AbstractSystem,
3434
mat::Material
3535
paramsetup::Params
3636
storage::Storage
37-
psets::Dict{Symbol,Vector{Int}}
38-
sdbcs::Vector{SingleDimBC}
39-
pdsdbcs::Vector{PosDepSingleDimBC}
40-
databcs::Vector{DataBC}
37+
condhandler::ConditionHandler
4138
cells::Vector{MeshCell{VTKCellType,Tuple{Int64}}}
4239
end
4340

@@ -48,13 +45,9 @@ function BodyChunk(body::AbstractBody, solver::AbstractTimeSolver, pd::PointDeco
4845
system = get_system(body, pd, chunk_id)
4946
paramsetup = get_paramsetup(body, system.chunk_handler, param_spec)
5047
storage = get_storage(mat, solver, system)
51-
psets = localized_point_sets(body.point_sets, system.chunk_handler)
52-
sdbcs = body.single_dim_bcs
53-
pdsdbcs = body.posdep_single_dim_bcs
54-
databcs = body.data_bcs
48+
condhandler = ConditionHandler(body, system)
5549
cells = get_cells(get_n_loc_points(system))
56-
chunk = BodyChunk(body_name, system, mat, paramsetup, storage, psets, sdbcs,
57-
pdsdbcs, databcs, cells)
50+
chunk = BodyChunk(body_name, system, mat, paramsetup, storage, condhandler, cells)
5851
return chunk
5952
end
6053

@@ -72,9 +65,20 @@ end
7265

7366
@inline each_point_idx(chunk::AbstractBodyChunk) = each_point_idx(chunk.system)
7467
@inline each_point_idx_pair(chunk::AbstractBodyChunk) = each_point_idx_pair(chunk.system)
68+
@inline each_dof_idx(chunk::AbstractBodyChunk) = each_dof_idx(chunk.system)
69+
@inline each_loc_dof_idx(chunk::AbstractBodyChunk) = each_loc_dof_idx(chunk.system)
70+
@inline each_dof(chunk::AbstractBodyChunk) = each_dof(chunk.system)
71+
@inline each_loc_dof(chunk::AbstractBodyChunk) = each_loc_dof(chunk.system)
72+
@inline each_dim(chunk::AbstractBodyChunk) = each_dim(chunk.system)
7573

76-
@inline n_loc_points(chunk::AbstractBodyChunk) = get_n_loc_points(chunk.system)
77-
@inline n_points(chunk::AbstractBodyChunk) = get_n_points(chunk.system)
74+
@inline get_n_loc_points(chunk::AbstractBodyChunk) = get_n_loc_points(chunk.system)
75+
@inline get_n_points(chunk::AbstractBodyChunk) = get_n_points(chunk.system)
76+
@inline get_n_dof(chunk::AbstractBodyChunk) = get_n_dof(chunk.system)
77+
@inline get_n_loc_dof(chunk::AbstractBodyChunk) = get_n_loc_dof(chunk.system)
78+
@inline get_n_dim(chunk::AbstractBodyChunk) = get_n_dim(chunk.system)
79+
80+
@inline free_dofs(chunk::AbstractBodyChunk) = free_dofs(chunk.condhandler)
81+
@inline constrained_dofs(chunk::AbstractBodyChunk) = constrained_dofs(chunk.condhandler)
7882

7983
function initialize!(::AbstractBodyChunk)
8084
return nothing

src/discretization/bond_associated_system.jl

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,9 @@ end
1414

1515
function BondAssociatedSystem(body::AbstractBody, pd::PointDecomposition, chunk_id::Int)
1616
check_bond_associated_system_compat(body.mat)
17-
loc_points = pd.decomp[chunk_id]
18-
bonds, n_neighbors = find_bonds(body, loc_points)
19-
bond_ids = find_bond_ids(n_neighbors)
20-
intersection_bond_ids = find_intersection_bond_ids(body, loc_points, bonds, bond_ids)
21-
chunk_handler = get_chunk_handler(bonds, pd, chunk_id)
22-
localize!(bonds, chunk_handler.localizer)
17+
bonds, n_neighbors, bond_ids, chunk_handler = get_bond_data(body, pd, chunk_id)
18+
intersection_bond_ids = find_intersection_bond_ids(body, chunk_handler.loc_points,
19+
bonds, bond_ids)
2320
position, volume = get_pos_and_vol_chunk(body, chunk_handler.point_ids)
2421
hood_volume = zeros(get_n_points(chunk_handler))
2522
ba_hood_volume = zeros(length(bonds))

src/discretization/bond_system.jl

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,7 @@ end
5454

5555
function BondSystem(body::AbstractBody, pd::PointDecomposition, chunk_id::Int)
5656
check_bond_system_compat(body.mat)
57-
bonds, n_neighbors = find_bonds(body, pd.decomp[chunk_id])
58-
bond_ids = find_bond_ids(n_neighbors)
59-
chunk_handler = get_chunk_handler(bonds, pd, chunk_id)
60-
localize!(bonds, chunk_handler.localizer)
57+
bonds, n_neighbors, bond_ids, chunk_handler = get_bond_data(body, pd, chunk_id)
6158
position, volume = get_pos_and_vol_chunk(body, chunk_handler.point_ids)
6259
correction = get_correction(body.mat, chunk_handler.n_loc_points,
6360
length(chunk_handler.point_ids), length(bonds))
@@ -67,6 +64,16 @@ function BondSystem(body::AbstractBody, pd::PointDecomposition, chunk_id::Int)
6764
return system
6865
end
6966

67+
function get_bond_data(body::AbstractBody, pd::PointDecomposition, chunk_id)
68+
loc_points = pd.decomp[chunk_id]
69+
bonds, n_neighbors = find_bonds(body, loc_points)
70+
halo_points = find_halo_points(bonds, loc_points)
71+
chunk_handler = ChunkHandler(pd, halo_points, chunk_id)
72+
localize!(bonds, chunk_handler.localizer)
73+
bond_ids = find_bond_ids(n_neighbors)
74+
return bonds, n_neighbors, bond_ids, chunk_handler
75+
end
76+
7077
function get_system(body::AbstractBody{Material}, pd::PointDecomposition,
7178
chunk_id::Int) where {Material<:AbstractBondSystemMaterial}
7279
return BondSystem(body, pd, chunk_id)
@@ -86,7 +93,7 @@ function check_bond_system_compat(::AbstractBondSystemMaterial)
8693
return nothing
8794
end
8895

89-
function find_bonds(body::AbstractBody, loc_points::UnitRange{Int})
96+
function find_bonds(body::AbstractBody, loc_points::AbstractVector{Int})
9097
δmax = maximum_horizon(body)
9198
nhs = GridNeighborhoodSearch{3}(search_radius=δmax, n_points=body.n_points)
9299
initialize_grid!(nhs, body.position)
@@ -125,15 +132,15 @@ end
125132
end
126133

127134
function filter_bonds!(bonds::Vector{Bond}, n_neighbors::Vector{Int},
128-
loc_points::UnitRange{Int}, body::AbstractBody)
135+
loc_points::AbstractVector{Int}, body::AbstractBody)
129136
for crack in body.point_sets_precracks
130137
filter_bonds_by_crack!(bonds, n_neighbors, loc_points, crack, body)
131138
end
132139
return nothing
133140
end
134141

135142
function filter_bonds_by_crack!(bonds::Vector{Bond}, n_neighbors::Vector{Int},
136-
loc_points::UnitRange{Int}, crack::PointSetsPreCrack,
143+
loc_points::AbstractVector{Int}, crack::PointSetsPreCrack,
137144
body::AbstractBody)
138145
filter_bonds(crack) || return nothing
139146
set_a, set_b = body.point_sets[crack.set_a], body.point_sets[crack.set_b]
@@ -174,17 +181,6 @@ function get_pos_and_vol_chunk(body::AbstractBody, point_ids::AbstractVector{<:I
174181
return position, volume
175182
end
176183

177-
function get_chunk_handler(bonds::Vector{Bond}, pd::PointDecomposition, chunk_id::Int)
178-
loc_points = pd.decomp[chunk_id]
179-
n_loc_points = length(loc_points)
180-
halo_points = find_halo_points(bonds, loc_points)
181-
hidxs_by_src = sort_halo_by_src!(halo_points, pd.point_src, length(loc_points))
182-
point_ids = vcat(loc_points, halo_points)
183-
localizer = find_localizer(point_ids)
184-
return ChunkHandler(n_loc_points, point_ids, loc_points, halo_points, hidxs_by_src,
185-
localizer)
186-
end
187-
188184
function find_kernels(body::AbstractBody, chunk_handler::ChunkHandler, bonds::Vector{Bond},
189185
bond_ids::Vector{UnitRange{Int}})
190186
hasproperty(body.mat, :kernel) || return Vector{Float64}()
@@ -208,7 +204,7 @@ end
208204
return system.kernels[bond_id]
209205
end
210206

211-
function find_halo_points(bonds::Vector{Bond}, loc_points::UnitRange{Int})
207+
function find_halo_points(bonds::Vector{Bond}, loc_points::AbstractVector{Int})
212208
halo_points = Vector{Int}()
213209
for bond in bonds
214210
j = bond.neighbor
@@ -219,7 +215,7 @@ function find_halo_points(bonds::Vector{Bond}, loc_points::UnitRange{Int})
219215
return halo_points
220216
end
221217

222-
@inline each_bond_idx(system::AbstractBondSystem, point_id::Int) = system.bond_ids[point_id]
218+
@inline each_bond_idx(system::AbstractBondSystem, i::Int) = system.bond_ids[i]
223219

224220
function localize!(bonds::Vector{Bond}, localizer::Dict{Int,Int})
225221
for i in eachindex(bonds)

src/discretization/chunk_handler.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ A type to handle a body chunk and its communication to other chunks.
1212
- `loc_points::UnitRange{Int}`: Indices of local points of the chunk.
1313
- `halo_points::Vector{Int}`: Indices of halo points of the chunk.
1414
- `hidxs_by_src::Dict{Int,UnitRange{Int}}`: Dict specifying the indices of halo Points
15-
depending on the body chunk they belong to.
15+
depending on the body chunk they belong to. So `body_chunk => indices`, with indices
16+
being the indices of the halo points in `point_ids`.
1617
- `localizer::Dict{Int,Int}`: Localizes global indices to local indices in this chunk.
1718
"""
1819
struct ChunkHandler <: AbstractChunkHandler
@@ -24,6 +25,17 @@ struct ChunkHandler <: AbstractChunkHandler
2425
localizer::Dict{Int,Int}
2526
end
2627

28+
function ChunkHandler(pd::PointDecomposition, halo_points::Vector{Int}, chunk_id::Int)
29+
loc_points = pd.decomp[chunk_id]
30+
n_loc_points = length(loc_points)
31+
hidxs_by_src = sort_halo_by_src!(halo_points, pd.point_src, length(loc_points))
32+
point_ids = vcat(loc_points, halo_points)
33+
localizer = find_localizer(point_ids)
34+
chunk_handler = ChunkHandler(n_loc_points, point_ids, loc_points, halo_points,
35+
hidxs_by_src, localizer)
36+
return chunk_handler
37+
end
38+
2739
for __field in fieldnames(ChunkHandler)
2840
local __funcname = Symbol("get_$(__field)")
2941
local __accessor_func = quote

0 commit comments

Comments
 (0)