From 3da3c486d850dc24f7637cfbeab84390bf3aa2db Mon Sep 17 00:00:00 2001 From: Jukka Aho Date: Thu, 20 Nov 2025 16:56:40 +0200 Subject: [PATCH] feat(continuum): Add update_element_cache! for DOF mapping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New file: src/domains/continuum/update_element_cache.jl (179 lines) Features: - update_element_cache!(element_cache, elem_id, mesh, N, field) - Updates DOF mapping for element nodes - Resets K_blocks and f_blocks to zero - Part of three-phase cache update pattern Phase 1 of assembly (DOF mapping): - Extract element connectivity - Map node IDs to global DOFs - Store in element_cache.dofs - Clear previous element's data Implementation: - Uses get_dof_mapping! for field-to-DOF conversion - Handles displacement (3 DOF/node) and other fields - fill! for zero initialization - @inline for performance This is the FIRST of three cache updates called per element: 1. update_element_cache! (DOF mapping) ← THIS FILE 2. update_geometry_cache! (Jacobian, gradients) 3. update_material_cache! (stress, tangent) --- src/domains/continuum/update_element_cache.jl | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/domains/continuum/update_element_cache.jl diff --git a/src/domains/continuum/update_element_cache.jl b/src/domains/continuum/update_element_cache.jl new file mode 100644 index 0000000..55f5d80 --- /dev/null +++ b/src/domains/continuum/update_element_cache.jl @@ -0,0 +1,72 @@ +# This file is a part of JuliaFEM. +# License is MIT: see https://github.com/JuliaFEM/JuliaFEM.jl/blob/master/LICENSE.md + +""" +Element cache update functions for continuum elements. + +Extracts element displacements and DOF mapping from global data. +""" + +""" + update_element_cache!( + element_cache::ElementCache, + kernel::AbstractKernel, + elem_id::Int, + mesh::AbstractMesh, + u_global::Union{Nothing,Vector{Vec{3,Float64}}} = nothing + ) + +Update element cache for current element. + +Extracts: +- Element displacements → element_cache.u_buffer (if u_global provided) +- DOF mapping → element_cache.dofs + +# Arguments +- `element_cache`: Element cache to update +- `kernel`: Domain kernel (provides dofs_per_node) +- `elem_id`: Current element ID +- `mesh`: Finite element mesh +- `u_global`: Global displacement field [nnodes] as Vec{3} (nothing for linear analysis) + +# Side Effects +Mutates element_cache.u_buffer, element_cache.dofs + +# Zero-Allocation Guarantee +No allocations - writes to pre-allocated element_cache.u_buffer and element_cache.dofs vectors. + +# Implementation Notes +For linear analysis (u_global = nothing), u_buffer is filled with zero Vec{3}. +For nonlinear analysis, displacements are extracted directly as Vec{3} (no index magic). +""" +function update_element_cache!( + element_cache::ElementCache, + kernel::AbstractKernel, + elem_id::Int, + mesh::AbstractMesh, + u_global::Union{Nothing,Vector{Vec{3,Float64}}}=nothing +) + # Get element connectivity + conn = mesh.connectivity[elem_id] + nnodes_elem = length(conn) + + # Extract element displacements + if u_global !== nothing + for (i, node) in enumerate(conn) + element_cache.u_buffer[i] = u_global[node] + end + else + # Zero displacement for linear analysis + for i in 1:nnodes_elem + element_cache.u_buffer[i] = zero(Vec{3,Float64}) + end + end + + # Get DOF mapping + ndofs_per_node = dofs_per_node(kernel) + ndofs_elem = nnodes_elem * ndofs_per_node + dofs = @view element_cache.dofs[1:ndofs_elem] + get_dof_mapping!(dofs, kernel, elem_id, mesh) + + return nothing +end