Explains why JuliaFEM uses nodal assembly instead of element assembly:
Five major advantages:
1. No atomic operations on GPU (each node writes to own DOFs)
2. Contact mechanics is natural (forces at nodes, not elements)
3. Clean domain decomposition (explicit node ownership for MPI)
4. Better cache locality (sequential node processing)
5. Adaptive refinement easier (local node operations)
Key data structure:
- NodeSet contains nodes + elements + node_to_elements connectivity
- Inverse connectivity enables gathering from connected elements
- Fields accessed via node_set.fields (type-stable)
Algorithm:
- Loop over nodes (not elements)
- Each node gathers contributions from connected elements
- Direct write to owned DOFs (no race conditions)
- Perfect for matrix-free Krylov methods
Validated with demo:
- CPU/GPU results match exactly (0.0 relative error)
- Average 3.24 elements per node (efficient gathering)
- Natural integration with contact mechanics
Compares to traditional element assembly:
- Element: scatter to nodes (atomic ops, cache misses)
- Nodal: gather from elements (no atomics, better cache)