Assemble several elements at a time

Now assemble! takes a vector of elements as input. This makes it
possible to preallocate memory for common matrices making code super
fast.
This commit is contained in:
Jukka Aho
2017-08-17 16:27:00 +03:00
parent aabcda2e26
commit ef66a8f74b
6 changed files with 27 additions and 42 deletions
+2 -4
View File
@@ -37,9 +37,7 @@ function assemble!(problem::Problem, time=0.0; auto_initialize=true)
if method_exists(assemble_prehook!, Tuple{typeof(problem), Float64})
assemble_prehook!(problem, time)
end
for element in get_elements(problem)
assemble!(problem.assembly, problem, element, time)
end
assemble!(get_assembly(problem), problem, get_elements(problem), time)
if method_exists(assemble_posthook!, Tuple{typeof(problem), Float64})
assemble_posthook!(problem, time)
end
@@ -73,7 +71,7 @@ function assemble!(problem::Problem, time::Real, ::Type{Val{:mass_matrix}}; dens
end
end
function assemble!(assembly::Assembly, problem::Problem, elements::Vector{Element}, time::Real)
function assemble!(assembly::Assembly, problem::Problem, elements::Vector{Element}, time)
warn("assemble!() this is default assemble operation, decreased performance can be expected without preallocation of memory!")
for element in elements
assemble!(assembly, problem, element, time)
+14 -29
View File
@@ -54,18 +54,23 @@ function get_formulation_type(problem::Problem{Elasticity})
end
"""
assemble!(assembly:Assembly, problem::Problem{Elasticity}, elements, time)
Start finite element assembly procedure for Elasticity problem.
Function groups elements to arrays by their type and assembles one element type
at time. This makes it possible to pre-allocate matrices common to same type
of elements.
"""
function assemble!(assembly::Assembly, problem::Problem{Elasticity}, elements::Vector{Element}, time)
assemble!(assembly, problem, elements, time, Val{problem.properties.formulation})
end
"""
This is for backward compatibility, will be removed asap.
"""
function assemble!(assembly::Assembly, problem::Problem{Elasticity}, element::Element, time)
warn("try to avoid single element assembly function as it's not possible to preallocate causing a slow code")
assemble!(assembly, problem, [element], time, Val{problem.properties.formulation})
formulation = Val{problem.properties.formulation}
element_types = unique(map(get_element_type, elements))
for element_type in element_types
elements_subset = filter_by_element_type(element_type, elements)
elements_subset = [element for element in elements_subset]
nelements = length(elements_subset)
assemble!(assembly, problem, elements_subset, time, formulation)
end
end
include("problems_elasticity_2d.jl")
@@ -102,26 +107,6 @@ function get_keys(element)
map(x -> all_keys[x], idx)
end
""" Continuum elements assembly entry point.
This splits elements to arrays by their type and assemble one element type
at time. This makes it possible to pre-allocate matrices common to same type
of elements.
"""
function assemble!(assembly::Assembly, problem::Problem{Elasticity},
all_elements::Vector{Element}, time, ::Type{Val{:continuum}})
element_types = unique(map(get_element_type, all_elements))
for element_type in element_types
elements = filter_by_element_type(element_type, all_elements)
# FIXME: there must be better way to do this
# to promote array for certain elemene type
elements = [element for element in elements]
nelements = length(elements)
debug("elasticity 3d: assembling $nelements of type $element_type")
assemble!(assembly, problem, elements, time, Val{:continuum})
end
end
""" Assemble 3d continuum elements in general solid mechanics problem. """
function assemble!{El<:Elasticity3DVolumeElements}(assembly::Assembly,