Assembly
Ferrite.start_assemble — Function
start_assemble(K::AbstractSparseMatrixCSC{Tv}; fillzero = true, atomic = false) -> CSCAssembler{Tv}
start_assemble(K::AbstractSparseMatrixCSC{Tv}, f::Vector{Tv}; fillzero = true, atomic = false) -> CSCAssembler{Tv}Create a CSCAssembler{Tv} from the matrix K and optional vector f with value type Tv.
start_assemble(K::Symmetric{AbstractSparseMatrixCSC{Tv}}; fillzero = true, atomic = false) -> SymmetricCSCAssembler{Tv}start_assemble(K::Symmetric{AbstractSparseMatrixCSC{Tv}}, f::Vector = Tv[]; fillzero = true, atomic = false) -> SymmetricCSCAssembler{Tv}Create a SymmetricCSCAssembler{Tv} from the matrix K and optional vector f with value type Tv. Only upper-triangle storage (Symmetric(K, :U)) is supported.
CSCAssembler and SymmetricCSCAssembler allocate workspace necessary for efficient matrix assembly. To assemble the contribution from an element, use assemble!.
The keyword argument fillzero can be set to false if K and f should not be zeroed out, but instead keep their current values.
The keyword argument atomic can be set to true to make the accumulation into K and f use atomic additions. This makes it safe to assemble from multiple concurrent tasks without partitioning the cells into independent sets ("grid coloring"), at the cost of some overhead and a non-deterministic result: the order in which contributions are added to a given entry depends on the task scheduling, and floating point addition is not associative. Atomic accumulation is only supported for the value types Float16, Float32, and Float64, and Complex of these (other value types throw an ArgumentError). Note that each task still needs its own assembler since the assembler contains buffers that are modified during assemble!. Note also that the value of atomic determines a type parameter of the returned assembler, so for a type stable setup the value should be a literal (or otherwise a compile time constant). See the howto on multithreaded assembly for more details.
Depending on the loaded extensions more assembly formats become available through this interface.
Ferrite.assemble! — Function
assemble!(a::COOAssembler, dofs, Ke)
assemble!(a::COOAssembler, dofs, Ke, fe)Assembles the element matrix Ke and element vector fe into a.
assemble!(a::COOAssembler, rowdofs, coldofs, Ke)Assembles the matrix Ke into a according to the dofs specified by rowdofs and coldofs.
assemble!(g, dofs, ge, atomic = Val(false))Assembles the element residual ge into the global residual vector g.
assemble!(A::Ferrite.AbstractAssembler, dofs::AbstractVector{Int}, Ke::AbstractMatrix)
assemble!(A::Ferrite.AbstractAssembler, dofs::AbstractVector{Int}, Ke::AbstractMatrix, fe::AbstractVector)Assemble the square element stiffness matrix Ke (and optional force vector fe) into the global stiffness (and force) in A, given the element degrees of freedom dofs.
This is equivalent to K[dofs, dofs] += Ke and f[dofs] += fe, where K is the global stiffness matrix and f the global force/residual vector, but more efficient.
assemble!(A::Ferrite.AbstractAssembler, rowdofs::AbstractVector{Int}, coldofs::AbstractVector{Int}, Ke::AbstractMatrix)assemble!(A::Ferrite.AbstractAssembler, rowdofs::AbstractVector{Int}, coldofs::AbstractVector{Int}, Ke::AbstractMatrix, fe::AbstractVector)Assemble the element stiffness matrix Ke (and optional force vector fe) into the global stiffness (and force) in A, given the element row degrees of freedom, rowdofs, and element column degrees of freedom, coldofs. This is equivalent to K[rowdofs, coldofs] += Ke and f[rowdofs] += fe, but more efficient.
For a symmetric assembler, rowdofs and coldofs must be equal. To assemble rectangular blocks with different row and column dofs, use a nonsymmetric assembler.
Ferrite.finish_assemble — Function
finish_assemble(a::COOAssembler) -> K, fFinalize the assembly and return the sparse matrix K::SparseMatrixCSC and vector f::Vector. If the assembler has not been used for vector assembly, f is an empty vector.
Multithreading
Ferrite.task_local_copy — Function
task_local_copy(x::T) -> TDuplicate x for a new task such that it can be used concurrently with the original x. This is similar to copy but only the data that is known to be mutated, i.e. "scratch data", are duplicated.
Typically, for concurrent assembly, there are some data structures that can't be shared between the tasks, for example the local element matrix/vector and the CellValues. task_local_copy can thus be used to duplicate these data structures for each task based on a "template" data structure. For example,
# "Template" local matrix and cell valuesKe = zeros(...)cv = CellValues(...)# Spawn `ntasks` tasks for concurrent assembly@sync for i in 1:ntasks Threads.@spawn begin Ke_task = task_local_copy(Ke) cv_task = task_local_copy(cv) for cell in cells_for_task assemble_element!(Ke_task, cv_task, ...) end endendSee the how-to on multi-threaded assembly for a complete example.
The following "user-facing" types define methods for task_local_copy:
CellValues,MultiFieldCellValues,FacetValues,InterfaceValues, andPointValuesare duplicated such that they can bereinit!ed independently.DenseArray(for e.g. the local matrix and vector) are duplicated such that they can be modified concurrently.CellCache,FacetCache, andInterfaceCache(for caching element nodes and dofs) are duplicated such that they can bereinit!ed independently.- Assemblers returned by
start_assembleare duplicated such that they can be used concurrently: the internal buffers are duplicated but the global matrix and vector are shared. Note that concurrent assembly still requires that tasks don't write to the same entries at the same time, e.g. by using grid coloring, or by using an atomic assembler (start_assemble(...; atomic = true)).
The following types also define methods for task_local_copy but are typically not used directly by the user but instead used recursively by the above types:
QuadratureRuleandFacetQuadratureRule- All types which are
isbitstype(e.g.Vec,Tensor,Int,Float64, etc.)