Commit Graph

1244 Commits

Author SHA1 Message Date
Jukka Aho 741da90819 feat(io): Add Gmsh mesh reader for tetrahedral meshes
- GmshMesh struct: nodes, elements, physical_groups storage
- read_gmsh_mesh() parses ASCII format 4.1 (.msh files)
- Extracts Tet4 elements (type 4) and node coordinates
- Reads physical groups for boundary conditions
- get_surface_nodes() placeholder for BC node extraction
- 175 lines: Simple mesh I/O for demos and benchmarks
2025-11-12 01:02:02 +02:00
Jukka Aho 2693bdf545 feat(assembly): Add nodal assembly data structures
- NodeToElementsMap: Inverse connectivity (node → elements touching it)
- ElementNodeInfo: Tracks element ID and local node index
- get_node_spider() finds all nodes coupling with given node
- NodalStiffnessContribution: Storage for 3×3 blocks per node
- matrix_vector_product_nodal() computes K_i*u at single node
- print_spider_info() debugging diagnostics
- 234 lines: Infrastructure for node-by-node assembly
2025-11-12 01:01:45 +02:00
Jukka Aho b4673290af feat(assembly): Add traditional element assembly data structures
- ElementAssemblyData: Global sparse matrix and force vectors
- ElementContribution: Local element contributions before scatter
- scatter_to_global!() adds element matrices to global system
- compute_residual!() calculates r = f_int - f_ext
- apply_dirichlet_bc!() penalty method for essential BCs
- get_dof_indices() node connectivity to global DOF mapping
- matrix_vector_product() sparse K*v multiplication
- 341 lines: Traditional element-by-element assembly infrastructure
2025-11-12 01:01:26 +02:00
Jukka Aho c0a0cc679b feat(backend): Add CPU backend with element assembly and CG solver
- ElasticityDataCPU struct wraps ElementAssemblyData
- initialize_backend() assembles global system from immutable Elements
- compute_element_stiffness() uses Tensors.jl (blocked by get_basis_derivatives)
- cg_solve() implements Conjugate Gradient iterative solver
- Supports Dirichlet boundary conditions from Physics API
- 228 lines: Traditional element assembly approach for CPU
2025-11-12 01:01:08 +02:00
Jukka Aho 40de86d4e4 feat(backend): Add abstract backend system with Auto/GPU/CPU selection
New file src/backend/abstract.jl defining backend abstraction:
- AbstractBackend base type for computation backend
- Auto() automatic backend selection (GPU if available, else CPU)
- GPU() force GPU backend (errors if CUDA unavailable)
- CPU(nthreads) force CPU backend with thread count
- select_backend() chooses concrete backend based on hardware
- AbstractElasticityData for backend-specific data structures
- ElasticitySolution struct for solve results
- solve!() dispatch point with backend parameter
- 241 lines with comprehensive API documentation
2025-11-12 00:59:40 +02:00
Jukka Aho 733c72b688 feat(materials): Add FiniteStrainPlasticity with multiplicative decomposition
New file src/materials/finite_strain_plasticity.jl implementing J2 plasticity for large deformations:
- FiniteStrainPlasticityState storing F_p (plastic deformation gradient), α_bar (backstress), κ
- FiniteStrainPlasticity struct with E, ν, σ_y, H parameters
- Hyperelastic stress response using Neo-Hookean
- Exponential map integration for plastic flow
- Pull-back/push-forward operations for intermediate configuration
- Consistent algorithmic tangent for Newton convergence
- 293 lines with comprehensive finite deformation theory
2025-11-12 00:59:18 +02:00
Jukka Aho 0e1f9778e7 feat(materials): Add PerfectPlasticity with radial return mapping
New file src/materials/perfect_plasticity.jl implementing J2 plasticity:
- PlasticityState struct storing plastic strain ε_p, backstress α, and κ
- PerfectPlasticity struct with E, ν, yield stress σ_y, hardening H
- Von Mises yield function: f = √(3/2)||dev(σ-α)|| - σ_y
- Radial return mapping algorithm for plastic updates
- Elastic predictor / plastic corrector scheme
- Kinematic hardening with backstress evolution
- Consistent tangent modulus for Newton convergence
- 357 lines with comprehensive theory and algorithm documentation
2025-11-12 00:58:57 +02:00
Jukka Aho 1a0066dea0 feat(materials): Add NeoHookean hyperelastic material with automatic differentiation
New file src/materials/neo_hookean.jl implementing simplest hyperelasticity:
- NeoHookean struct with shear modulus μ and Lamé parameter λ
- Convenience constructor from E and ν engineering constants
- strain_energy() computes ψ = μ/2·(I₁-3) - μ·ln(J) + λ/2·ln²(J)
- Stress S = 2·∂ψ/∂C via automatic differentiation
- Tangent 𝔻 = 4·∂²ψ/∂C² via automatic differentiation
- Uses Tensors.jl built-in AD (no ForwardDiff dependency)
- Total Lagrangian formulation with 2nd PK stress
- 253 lines with comprehensive theory documentation
2025-11-12 00:58:39 +02:00
Jukka Aho 8f198752ac feat(materials): Add LinearElastic material model with Tensors.jl
New file src/materials/linear_elastic.jl implementing Hooke's law:
- LinearElastic struct with Young's modulus E and Poisson's ratio ν
- Input validation: E > 0, -1 < ν < 0.5
- Helper functions: λ() and μ() compute Lamé parameters
- compute_stress() implements σ = λ·tr(ε)·I + 2μ·ε
- Tangent modulus: 𝔻 = λ·I⊗I + 2μ·��ˢʸᵐ
- Zero-allocation with SymmetricTensor types
- Simplified interface without state management
- 180 lines with comprehensive documentation
2025-11-12 00:58:23 +02:00
Jukka Aho ac071b5d57 feat(materials): Add AbstractMaterial type hierarchy and interface
New file src/materials/abstract_material.jl defining material model architecture:
- AbstractMaterial base type for all materials
- AbstractElasticMaterial for stateless materials (no history)
- AbstractPlasticMaterial for stateful materials (plastic strain, etc.)
- compute_stress() interface: (material, ε, state_old, Δt) → (σ, 𝔻, state_new)
- State management convention for Newton iterations
- Thread-safe and GPU-compatible design principles
- 229 lines with comprehensive documentation and examples
2025-11-12 00:58:06 +02:00
Jukka Aho 184919131e feat(physics): Add backend-agnostic physics API with BC types
New file src/physics_api.jl defining user-facing elasticity API:
- ElasticityPhysicsType (alias Elasticity) for problem configuration
- DirichletBC struct for prescribed displacements
- NeumannBC struct for surface tractions/pressures
- Physics{P} container for problem with elements and BCs
- Works with both CPU and GPU backends
- 183 lines with comprehensive examples
2025-11-12 00:57:33 +02:00
Jukka Aho 84a1bfec4e feat(physics): Add ElasticityPhysics type with geometric/material nonlinearity
New file src/physics/elasticity.jl:
- ElasticityPhysics struct implementing AbstractPhysics interface
- Formulations: plane_stress, plane_strain, continuum (3D)
- finite_strain flag for Green-Lagrange strain (geometric nonlinearity)
- geometric_stiffness flag for buckling analysis
- Field storage control: store_fields (converged), store_iteration_fields (debug)
- Interface methods: get_unknown_field_name, get_formulation_type, get_unknown_field_dimension
- should_store_field() for selective field storage
- 205 lines with comprehensive documentation and GPU design notes
2025-11-12 00:56:58 +02:00
Jukka Aho 628b902bf5 feat(physics): Add deformation gradient computation with strain formulations
New file src/physics/deformation_gradient.jl:
- compute_deformation_gradient() computes F = I + ∇u at integration points
- StrainFormulation types: FiniteStrain() and SmallStrain()
- Uses Tensors.jl for all tensor operations (Vec, Tensor)
- Zero-allocation design with @inline functions
- GPU-ready immutable operations
- Comprehensive mathematical documentation with references
- 243 lines including commented high-level API for future integration
2025-11-12 00:56:40 +02:00
Jukka Aho 258017922e feat(physics): Add assembly helper functions with Tensors.jl
New file src/physics/assembly_helpers.jl with FEM assembly utilities:
- shape_function_gradients() computes ∇N in current configuration
- compute_strain_from_gradients() small strain ε = sym(∇u)
- compute_green_lagrange_strain() finite strain E = ½(C-I)
- accumulate_stiffness!() adds element stiffness contributions
- accumulate_internal_forces!() computes f_int = ∫σ·∇N dV
- accumulate_external_forces!() computes f_ext = ∫N·b dV
- Zero-allocation design with Tensors.jl Vec and SymmetricTensor
- 331 lines with comprehensive performance documentation
2025-11-12 00:56:19 +02:00
Jukka Aho 4440f86691 feat(physics): Add AbstractPhysics base type and interface
New file src/physics/abstract.jl defining physics system architecture:
- AbstractPhysics base type for all physics implementations
- get_unknown_field_name() returns primary field (displacement, temperature, etc.)
- get_formulation_type() returns :incremental, :total, or :rate
- get_unknown_field_dimension() returns DOFs per node
- assemble!() dispatch point for physics-specific assembly
- Comprehensive docstrings covering multi-physics coupling and GPU compatibility
- 138 lines documenting design philosophy and future extension
2025-11-12 00:56:05 +02:00
Jukka Aho bb68e9de84 feat(geometry): Add Jacobian computation with Tensors.jl
New file src/geometry/jacobian.jl implementing geometric transformations:
- compute_jacobian(X, dN_dξ) computes J = ∂x/∂ξ using tensor products
- physical_derivatives(J, dN_dξ) transforms derivatives to physical space
- Full Tensors.jl integration with Vec and Tensor types
- Zero-allocation tuple-based API for performance
- AbstractVector overloads for compatibility
- Comprehensive docstrings with 2D/3D examples
- 169 lines with mathematical definitions and usage patterns
2025-11-12 00:55:10 +02:00
Jukka Aho 57ca301b86 fix(integration): Fix type inference in integration_points conversion
Modified src/integration/gauss.jl to fix IntegrationPoint creation:
- Changed from generator expression to ntuple for proper type inference
- Collect quad_data first (was zip iterator, cannot be indexed)
- Remove explicit type parameter {D} - let Julia infer from arguments
- Fixes type stability issue in integration point generation
- Maintains zero-allocation design with tuple return
2025-11-12 00:54:35 +02:00
Jukka Aho 1e59eb1bbc feat(integration): Add get_gauss_points! function with Tensors.jl Vec types
New file implementing Gauss quadrature point generation:
- get_gauss_points!(topology, scheme) returns tuple of (weight, Vec{D}) pairs
- Supports all 7 topologies: Segment, Triangle, Quadrilateral, Tetrahedron, Hexahedron, Wedge, Pyramid
- Orders 1-3 for each topology (exact integration up to quintic/cubic)
- Uses Tensors.jl Vec types for coordinates (GPU-friendly, zero-allocation)
- Fully inlined (@inline) for compile-time optimization
- 300 lines of quadrature rules from standard FEM references
2025-11-12 00:53:33 +02:00
Jukka Aho 07f1c690d2 refactor(topology): Update AbstractTopology documentation for separation of concerns
Modified src/topology/topology.jl to reflect new architecture:
- Clarify topology defines geometric shape only, not node count
- Document that node count comes from basis functions
- Add examples showing same topology with different bases (Quad4/8/9)
- Update docstring to reference new topology types (Segment, Triangle, etc.)
- Emphasize corner nodes only in topology API
- Remove references to old node-count-baked types (Tri3, Quad4, etc.)
2025-11-12 00:53:02 +02:00
Jukka Aho a4d5b235ca feat(topology): Add Wedge 3D topology with Wedge6/Wedge15 aliases
New file implementing 3D wedge/prism topology:
- Wedge struct with dim=3, 6 corner nodes (triangular prism)
- reference_coordinates() with bottom triangle at z=-1, top at z=1
- edges() returns 9 edges (3 bottom + 3 top + 3 vertical)
- faces() returns 5 faces (2 triangular ends + 3 quadrilateral sides)
- Backward compatibility aliases: Wedge6 (linear), Wedge15 (quadratic)
- Zero-allocation tuple-based design
2025-11-12 00:52:38 +02:00
Jukka Aho f7d778d960 feat(topology): Add Pyramid 3D topology with Pyr5 alias
New file implementing 3D pyramidal topology:
- Pyramid struct with dim=3, 5 corner nodes (square base + apex)
- reference_coordinates() with base at z=0 and apex at (0,0,1)
- edges() returns 8 edges (4 base + 4 to apex)
- faces() returns 5 faces (1 quadrilateral base + 4 triangular sides)
- Backward compatibility alias: Pyr5 (linear)
- Zero-allocation tuple-based design
2025-11-12 00:52:26 +02:00
Jukka Aho 0231b2e33a feat(topology): Add Hexahedron 3D topology with Hex8/Hex20/Hex27 aliases
New file implementing 3D hexahedral topology:
- Hexahedron struct with dim=3, 8 corner nodes (3D tensor product)
- reference_coordinates() in [-1,1]³ cube
- edges() returns 12 edges, faces() returns 6 quadrilateral faces
- Backward compatibility aliases: Hex8, Hex20 (Serendipity), Hex27 (Lagrange)
- Supports trilinear, serendipity (no interior), and full tensor product bases
- Zero-allocation tuple-based design
2025-11-12 00:52:13 +02:00
Jukka Aho 02e40946ef feat(topology): Add Tetrahedron 3D topology with Tet4/Tet10 aliases
New file implementing 3D tetrahedral topology:
- Tetrahedron struct with dim=3, 4 corner nodes (3D simplex)
- reference_coordinates() at (0,0,0), (1,0,0), (0,1,0), (0,0,1)
- edges() returns 6 edges, faces() returns 4 triangular faces
- Backward compatibility aliases: Tet4 (linear), Tet10 (quadratic)
- Zero-allocation tuple-based design
2025-11-12 00:52:00 +02:00
Jukka Aho 6a5a87daef feat(topology): Add Quadrilateral 2D topology with Quad4/Quad8/Quad9 aliases
New file implementing 2D quadrilateral topology:
- Quadrilateral struct with dim=2, 4 corner nodes at (-1,-1), (1,-1), (1,1), (-1,1)
- edges() returns 4 edges, faces() returns element itself
- Backward compatibility aliases: Quad4, Quad8 (Serendipity), Quad9 (Lagrange)
- Supports bilinear, serendipity (no center), and full tensor product bases
- Zero-allocation tuple-based design
2025-11-12 00:51:47 +02:00
Jukka Aho 1ab8f3f30c feat(topology): Add Triangle 2D topology with Tri3/Tri6/Tri7 aliases
New file implementing 2D triangular topology:
- Triangle struct with dim=2, 3 corner nodes
- reference_coordinates() at (0,0), (1,0), (0,1)
- edges() returns 3 edges, faces() returns element itself
- Backward compatibility aliases: Tri3, Tri6, Tri7 (same topology, different basis)
- Zero-allocation tuple-based design
- Separation: topology is geometric shape, basis determines node count
2025-11-12 00:51:25 +02:00
Jukka Aho f547f547e8 feat(topology): Add Segment 1D topology with Seg2/Seg3 aliases
New file implementing 1D line segment topology:
- Segment struct with dim=1, 2 corner nodes
- reference_coordinates() returns (-1.0,) and (1.0,)
- edges() and faces() for topology connectivity
- Backward compatibility aliases: Seg2, Seg3 (same topology, different basis)
- Zero-allocation design using tuples
- Separation of concerns: topology defines shape, basis determines node count
2025-11-12 00:50:58 +02:00
Jukka Aho e2917cdba8 docs: Add ADR-005 on integration point indices architecture
Document decision to store integration point indices instead of data in Element struct.
Key rationale: Elements should store relationships (indices), not data, for memory
efficiency and consistency with node connectivity pattern. Aligns with nodal assembly
approach and GPU-friendly architecture.
2025-11-12 00:49:17 +02:00
Jukka Aho ba0afce933 docs: Add ADR-004 for zero-allocation integration points API
Architectural Decision Record documenting design of integration points
API for high-performance finite element assembly.

Decision: Compile-time function returning tuple of (weight, Vec{D})
matching eval_basis! zero-cost abstraction pattern.

Problem context:
- OLD API: Runtime dispatch with mutable struct containing Dict
- Performance penalty: ~50× slower due to type instability
- Allocations: New struct created every query
- Impact: Millions of calls during assembly

Solution properties:
- Compile-time generation (fully inlined)
- Vec{D} from Tensors.jl for FEM math
- Zero allocation (tuples, stack-only)
- Type-stable (all types known at compile time)
- GPU compatible (no heap allocations)

API signature:
get_gauss_points!(::Type{Topology}, ::Type{Gauss{order}})
  → NTuple{N, Tuple{Float64, Vec{D}}}

Alternatives rejected:
- Plain tuples (less convenient for FEM math)
- Store in element (overhead, less flexible)
- Global constants (not composable)
- Runtime dispatch (type-unstable, slow)

Status: Accepted, implemented in src/integration/ (193 lines)
2025-11-12 00:44:29 +02:00
Jukka Aho 25af535745 demo: Add Tet10 CPU test and validation
CPU implementation test for 10-node tetrahedral elements validating
shape functions, derivatives, and assembly against analytical solutions.

Validation tests:
1. Shape function partition of unity (Σ N_i = 1)
2. Shape function derivatives correctness
3. Jacobian computation accuracy
4. Element stiffness matrix symmetry
5. Assembly convergence with mesh refinement
6. Comparison against Tet4 (linear elements)

Tet10 specifics tested:
- 10 shape functions (quadratic)
- 4-point Gauss quadrature
- Curved element geometry
- Mid-edge node positioning

Test problems:
- Patch test (constant strain)
- Pure bending (quadratic strain)
- Manufactured solution (known displacement field)

Expected results:
- Tet10 converges faster than Tet4 (fewer elements needed)
- Tet10 captures bending better (quadratic)
- Tet10 passes patch test exactly

Purpose: Establish correctness before GPU port
Reference for gpu_assembly_tet10.jl validation
2025-11-12 00:29:36 +02:00
Jukka Aho 69e3b131b5 demo: Add nodal assembly GPU implementation
GPU port of nodal assembly strategy with CUDA kernels demonstrating
atomic-free assembly on GPU using node-parallel approach.

GPU kernel design:
- One thread per node (not per element)
- Each thread gathers from touching elements
- No atomic operations (node ownership)
- Coalesced memory access via node ordering

Kernel structure:
- Thread ID maps to node ID
- Loop over elements touching this node
- Loop over element nodes for block contributions
- Compute 3×3 stiffness blocks with Tensors.jl
- Accumulate locally, write once to global

Data layout:
- node_to_elements: CSR-like structure on GPU
- Element data: Array of Structs (immutable elements)
- Node displacement: Flat vector (3*n_nodes)
- Result: Flat vector (3*n_nodes)

Performance characteristics:
- Memory bandwidth bound (not compute bound)
- Benefits from coalescing (sequential node access)
- Scalable to multi-GPU (domain decomposition)
- No synchronization within kernel

Comparison to element assembly:
- Element: N_elem threads, atomic scatter
- Nodal: N_nodes threads, no atomics

Reference: CPU version in nodal_assembly_cpu.jl
2025-11-12 00:29:21 +02:00
Jukka Aho 4040a802e5 demo: Add nodal assembly CPU implementation
CPU implementation of nodal assembly strategy (loop over nodes, not
elements) demonstrating modern assembly approach for FEM.

Nodal assembly concept:
- Traditional: Loop over elements, scatter to nodes (atomics needed on GPU)
- Modern: Loop over nodes, gather from elements (no atomics, better GPU)

Algorithm:

Advantages:
- No atomic operations (each node owned by one thread)
- Natural 3×3 block structure (displacement DOFs)
- Contact-ready (contact is naturally nodal)
- GPU-friendly (coalesced memory access)

Implementation:
- Node-to-elements connectivity graph
- Block-based operations with Tensors.jl
- Zero-allocation assembly loop
- Matrix-free operator for iterative solvers

Reference: docs/src/book/multigpu_nodal_assembly.md
2025-11-12 00:29:03 +02:00
Jukka Aho 0bc41c7cf1 demo: Add Newton-Krylov-Anderson CPU reference implementation
Complete CPU reference implementation of Newton-Krylov solver with
Anderson acceleration for nonlinear elasticity with plasticity.

Solver components:
- Newton outer loop (nonlinear iterations)
- GMRES inner loop (linear solve, matrix-free)
- Anderson acceleration (convergence improvement)
- Adaptive GMRES tolerance (Eisenstat-Walker formula)

Matrix-free strategy:
- No tangent matrix assembly
- Jacobian-vector product via finite differences: J·v ≈ [r(u+ε·v)-r(u)]/ε
- Residual assembly: r(u) = f_int(u) - f_ext
- Each GMRES iteration = 2 residual evaluations

Plasticity handling:
- Radial return mapping at each Gauss point
- Material state tracking (ε_p, α) during iterations
- State update only on Newton convergence
- Von Mises yield criterion with perfect plasticity

Reference for GPU implementation:
- Validates numerical correctness
- Establishes performance baseline
- Documents algorithm flow for GPU port
- Shows data dependencies and kernel opportunities

Problem: 3D elasticity with J2 plasticity, Tet4 mesh
2025-11-12 00:28:45 +02:00
Jukka Aho 3daed70615 demo: Add GPU assembly for Tet10 higher-order elements
GPU implementation for 10-node tetrahedral elements demonstrating
higher-order finite elements with quadratic shape functions.

Tet10 specifics:
- 10 nodes per element (vertices + edge midpoints)
- 4-point Gauss quadrature (order 2)
- Quadratic shape functions (N_i second-order polynomials)
- Shape function derivatives via analytical formulas

Challenges vs Tet4:
- More integration points (4 vs 1)
- More DOFs per element (30 vs 12)
- More complex shape functions
- Larger local stiffness (10×10 vs 4×4 blocks)

GPU kernel modifications:
- Loop over 4 Gauss points instead of 1
- Evaluate quadratic shape functions at each IP
- Accumulate contributions from all IPs
- Scatter 30 DOFs per element (not 12)

Benefits of Tet10:
- Better stress/strain representation
- Fewer elements needed for accuracy
- Curved boundary representation
- Higher convergence rate

Same problem setup: 3D cantilever with steel properties
Test validates GPU higher-order element implementation (430 lines).
2025-11-12 00:28:24 +02:00
Jukka Aho 036331d82e demo: Add Tensors.jl-corrected GPU assembly POC
Corrected GPU assembly using proper Tensors.jl material modeling
instead of plain vectors with manual indexing.

Architectural improvements:
- SymmetricTensor{2,2} for 2D strain and stress
- Material API: compute_stress(material, ε)
- LinearElastic struct with Lamé parameters
- Hooke's law: σ = λ·tr(ε)·I + 2μ·ε (matches theory)
- Clean tensor operations (no manual indexing)

Versus original POC (gpu_assembly_poc.jl):
- OLD: ε = SA[εxx, εyy, γxy] (plain vector)
- NEW: ε = SymmetricTensor{2,2}((εxx, γxy/2, εyy))
- OLD: σ = C * ε (matrix multiply)
- NEW: σ = compute_stress(material, ε) (material API)
- OLD: Manual stress component indexing
- NEW: Tensor operations (Bᵀ·σ via dot product)

Benefits:
- Follows material_modeling.md architecture
- GPU compatible (Tensors.jl works on CUDA)
- Maintainable (material models pluggable)
- Mathematics matches equations

Same test case: 10×10 Quad4, steel, 242 DOFs (468 lines).
2025-11-12 00:28:07 +02:00
Jukka Aho 34027e887f demo: Add initial GPU assembly proof-of-concept
First working GPU assembly implementation (proof-of-concept stage)
demonstrating complete FEM solve staying on GPU for 2D elasticity.

Implementation:
- Element-parallel GPU kernel for Quad4 elements
- 2×2 Gauss quadrature on GPU
- Plain vector approach (before Tensors.jl integration)
- Matrix-free Jacobian-vector product
- Complete Newton-Krylov loop on GPU
- BC enforcement via masking

Test case: 10×10 Quad4 mesh (100 elements, 242 DOFs)
- Material: Steel (E=200 GPa, ν=0.3)
- BC: Fixed left edge, displacement on right edge

Architecture validation:
- GPU assembly matches CPU (error < 1e-15)
- Entire solve stays on GPU (no ping-pong)
- Only transfers: mesh (once) + u0/u_final (boundary)

Note: This is the initial version using plain vectors and manual
indexing. See gpu_assembly_poc_tensors.jl for corrected version
using proper Tensors.jl material API (606 lines).
2025-11-12 00:27:51 +02:00
Jukka Aho 6fd50689b6 demo: Add cantilever physics-based GPU assembly
GPU assembly using physics-aware abstractions (elasticity helper functions)
instead of raw kernel implementation, demonstrating higher-level API.

Architecture difference from cantilever_gmsh_gpu.jl:
- Raw GPU: Direct CUDA kernels with manual indexing
- Physics GPU: Helper functions (compute_strain, compute_stress, etc.)

Physics abstractions:
- compute_jacobian: J = Σ dN ⊗ X (automatic differentiation possible)
- compute_strain: ε = sym(Σ dN ⊗ u) using Tensors.jl
- compute_stress: σ = material(ε) with material API
- compute_residual: r = Σ Bᵀ·σ·w (internal forces)

Benefits:
- More readable (physics equations explicit)
- More maintainable (abstractions hide complexity)
- More extensible (swap materials easily)
- Still GPU-compatible (Tensors.jl works on CUDA)

Trade-offs:
- Slightly higher abstraction overhead
- Depends on Tensors.jl GPU support
- May need careful inlining for performance

Same problem: 10m × 1m × 1m cantilever, Tet4, steel properties
2025-11-12 00:27:26 +02:00
Jukka Aho 0856714ce1 demo: Add cantilever beam GPU assembly with Gmsh
Complete GPU-accelerated FEM solve for 3D cantilever beam using
nodal assembly strategy and matrix-free Newton-Krylov solver.

GPU implementation:
- Gmsh mesh generation (same as CPU version)
- Data transfer to GPU (nodes, connectivity, BC)
- GPU kernels for nodal assembly (element contributions)
- Matrix-free Jacobian-vector product on GPU
- GMRES solver on GPU (Krylov.jl with CuArrays)
- CPU fallback for Anderson acceleration

Problem characteristics:
- Geometry: 10m × 1m × 1m cantilever beam
- Elements: Tet4 from Gmsh
- Material: Steel (E=210 GPa, ν=0.3)
- BC: Fixed left end, tip force on right end

Architecture:
- Single GPU transfer: mesh + BC → GPU at start
- Entire Newton-Krylov loop stays on GPU
- Single result transfer: u_final ← GPU at end
- No ping-pong between CPU and GPU during solve

Demonstrates complete GPU FEM pipeline from meshing to solution
with realistic geometry and material properties.
2025-11-12 00:27:02 +02:00
Jukka Aho cf364576f1 demo: Add cantilever CPU assembly comparison
Compares traditional element assembly vs nodal assembly on CPU for
cantilever beam example, validating assembly equivalence and measuring
performance characteristics.

Comparison:
- Element assembly: Traditional FEM (loop over elements, atomic scatter)
- Nodal assembly: Modern approach (loop over nodes, block operations)

Validation:
- Residual equivalence (element vs nodal assembly)
- Stiffness operator equivalence (matvec comparison)
- Assembly time comparison
- Memory allocation tracking

Problem: Same cantilever beam as cantilever_beam_simple.jl
- Tet4 mesh from Gmsh
- Steel properties
- Fixed left, force on right

Demonstrates CPU assembly strategies before GPU implementation,
establishing baseline for GPU performance comparison.
2025-11-12 00:26:32 +02:00
Jukka Aho 2ae1b686ed demo: Add simple cantilever beam example with Gmsh
Demonstrates modern Physics API for 3D elasticity on realistic geometry
using Gmsh mesh generation and both direct/iterative solvers.

Features:
- Gmsh mesh generation (10m × 1m × 1m cantilever beam)
- Tet4 elements with controlled mesh size (lc=1.5)
- Physics API setup (Elasticity, continuum formulation)
- Steel material properties (E=210 GPa, ν=0.3)
- Boundary conditions: Fixed left end, force on right end

Problem setup:
- Geometry: Cantilever beam (aspect ratio 10:1:1)
- Discretization: Tet4 elements from Gmsh
- Loading: Tip force applied via Neumann BC
- Constraints: Fixed end via Dirichlet BC

Workflow demonstration:
1. Mesh generation with Gmsh API
2. Physics problem creation
3. Solver setup (direct or iterative)
4. Post-processing and visualization

Educational example showing complete FEM workflow from meshing
to solution with modern JuliaFEM API (183 lines).
2025-11-12 00:21:54 +02:00
Jukka Aho e7f0309f73 demo: Add simple assembly strategy comparison
Demonstrates modern Physics API for solving elasticity problems using
CPU backend with element assembly.

Features:
- Simple 2-element beam mesh (Hex8 elements, 12 nodes, 36 DOFs)
- Immutable Element API with field-based material properties
- Physics problem setup (Elasticity, continuum formulation)
- Material properties: Steel (E=210 GPa, ν=0.3)

Demonstrates workflow:
1. Create mesh (nodes dictionary + connectivity tuples)
2. Create Physics problem (Elasticity with continuum formulation)
3. Build elements with immutable API (fields tuple)
4. Add elements to physics

Educational example showing modern API usage for elasticity
problems with clean separation between geometry and physics (131 lines).
2025-11-12 00:21:37 +02:00
Jukka Aho 875073c1c2 docs: Add Tensors.jl integration correction for GPU POC
Documents architectural correction from manual Voigt indexing to proper
Tensors.jl material modeling in GPU assembly proof-of-concept.

Problem identified:
- Initial POC used plain vectors instead of SymmetricTensor
- Hardcoded constitutive matrix instead of material API
- Manual index arithmetic for stress components
- Didn't match established material_modeling.md architecture

Solution implemented:
- SymmetricTensor{2,2} for 2D strain and stress
- Material API: compute_stress(material, ε)
- LinearElastic struct with Lamé parameters
- Clean tensor operations matching theory
- GPU compatible (Tensors.jl works on CUDA)

Key architectural changes:
1. Material model struct (LinearElastic with E, ν)
2. Material API with Hooke's law (σ = λ·tr(ε)·I + 2μ·ε)
3. SymmetricTensor strain computation (εxx, εyy, γxy/2)
4. Stress-to-force conversion (Bᵀ·σ operator)

Reference: demos/gpu_assembly_poc_tensors.jl (264 lines)
2025-11-12 00:21:15 +02:00
Jukka Aho 600a2eeb0a docs: Add GPU assembly proof-of-concept summary
Complete working proof-of-concept for GPU-accelerated finite element
assembly demonstrating entire solve staying on GPU.

Implementation features:
- Element-parallel GPU kernel for 2D linear elasticity
- Quad4 elements with 2×2 Gauss quadrature
- Matrix-free Jacobian-vector product (finite difference on GPU)
- Complete Newton-Krylov loop on GPU (no CPU escapes)
- Boundary condition enforcement

Validation results:
- GPU assembly matches CPU (relative error < 1e-15)
- Entire solve pipeline stays on GPU
- Only transfers: mesh (once), u0 (input), u_final (output)

Test case: 10×10 Quad4 mesh (100 elements, 242 DOFs), steel properties
(E=200 GPa, ν=0.3), fixed left edge, displacement on right edge.

Architecture: u0 → GPU → [Newton loop: residual + Jv + GMRES + update] → u_final

Reference: demos/gpu_assembly_poc.jl (212 lines documentation)
2025-11-12 00:20:49 +02:00
Jukka Aho 19c93b82de docs: Add GPU kernel implementation plan for Newton-Krylov-Anderson
Implementation roadmap for GPU-accelerated nonlinear solver pipeline derived
from CPU reference implementation (newton_krylov_anderson_cpu.jl).

Breakdown of solver pipeline:
- Outer loop: Newton iterations (residual assembly + line search)
- Middle loop: GMRES iterations (matrix-free matvec + Arnoldi)
- Inner operation: Element residual assembly with plasticity

Key GPU kernels identified:
1. Element residual assembly (workhorse kernel, nodal scatter with atomics)
2. Vector operations (standard cuBLAS: axpy, dot, norm)

Four-phase implementation strategy:
1. Single kernel test (residual assembly CPU vs GPU)
2. Matrix-free matvec test (Jacobian-vector product validation)
3. GMRES on GPU (Krylov.jl with CuArrays)
4. Complete pipeline (GPU main loop, CPU Anderson acceleration)

Includes plastic state GPU representation (NTuple vs SymmetricTensor),
kernel launch configuration, and atomic scatter pattern (296 lines).
2025-11-12 00:20:24 +02:00
Jukka Aho 2e48a356a3 bench: Add GPU benchmarks test script
Shell script for quick validation of GPU benchmarks without running
full suites (which can take minutes on large problem sizes).

Features:
- Julia installation check (version validation)
- GPU availability detection (nvidia-smi query)
- CUDA.jl functionality verification
- Quick state management test (10K elements, not 1M)
- Quick matrix-free test (1K DOFs, not 1M)
- Both CPU and GPU paths tested
- Error handling with informative messages

Runs small problem sizes to verify:
- Code compiles and loads correctly
- CUDA kernels launch without errors
- Basic functionality works before long benchmarks
- Development workflow (test before full run)

Executable: chmod +x benchmarks/test_gpu_benchmarks.sh (159 lines)
2025-11-12 00:19:50 +02:00
Jukka Aho 33bf912b99 bench: Add perfect plasticity material performance analysis
Comprehensive benchmarking of J2 plasticity with radial return mapping:

Tests performed:
1. Single evaluation: elastic path (below yield) vs plastic path
2. Zero-allocation verification for both branches
3. Type stability validation
4. State management overhead (fresh vs history)
5. Hardening parameter sensitivity analysis
6. Assembly loop simulation (realistic FEM usage)
7. Comparison to LinearElastic and NeoHookean
8. Strain level scalability (elastic to plastic transition)

Validates:
- Plastic path overhead (radial return vs elastic)
- State handling performance (PlasticityState vs NoState)
- Zero allocations maintained even with mutable state
- Type stability for both converged and trial states

Includes von Mises stress computation, yield surface check, and
algorithmic tangent calculation (320 lines).
2025-11-12 00:19:30 +02:00
Jukka Aho 783c075277 bench: Add Neo-Hookean hyperelastic material analysis
Detailed performance analysis of automatic differentiation overhead in
hyperelastic stress computation for Neo-Hookean material model.

Key analyses:
1. Single stress evaluation timing (typical FEM assembly use case)
2. Allocation verification (zero-allocation requirement)
3. Component breakdown (strain energy vs stress vs tangent)
4. Scaling with problem size (assembly loop performance)

Compares NeoHookean (AD) against LinearElastic (manual derivatives) to
quantify AD overhead in production FEM assembly loops.

Results inform whether AD is suitable for hot paths vs manual derivatives
for performance-critical material models (260 lines).
2025-11-12 00:19:10 +02:00
Jukka Aho d4abf2fd13 bench: Add matrix-free Newton-Krylov GPU benchmark
Comprehensive benchmark comparing three nonlinear solver strategies:
1. Traditional Newton (full Jacobian assembly + direct solve)
2. Matrix-free Newton-Krylov (GMRES, no Jacobian matrix)
3. Matrix-free with Anderson acceleration (accelerated convergence)

Problem: 3D nonlinear elasticity with cubic nonlinearity
- r(u) = K·u + β·(K·u)³ - f
- Jacobian-vector product via finite differences: J·v ≈ [r(u+ε·v) - r(u)]/ε

Key findings validated:
- Matrix-free eliminates Jacobian assembly cost
- Anderson acceleration reduces iteration count
- GPU acceleration for large problems (memory bandwidth bound)
- GMRES with adaptive tolerance (Eisenstat-Walker formula)

Includes both CPU and GPU implementations with performance comparison
showing memory usage, iteration counts, and wall-clock times for systems
ranging from 1K to 1M DOFs (835 lines, full implementation).
2025-11-12 00:18:46 +02:00
Jukka Aho a88167b0cb bench: Add material models benchmark execution results
Complete execution output from material_models_benchmark.jl validation:

Performance results:
- Linear Elastic: 5.1× speedup (Tensors.jl vs Voigt/Dict)
- Neo-Hookean Manual: 2.0× speedup over old approach
- Perfect Plasticity: 21.0× speedup (zero allocations vs Dict)
- Average speedup: 9.4× (validates 5-50× claim range)

Key validation:
- All new implementations: ZERO allocations (confirmed)
- Manual derivatives: 21.1× faster than automatic differentiation
- Type stability: All @code_warntype checks pass (no red flags)
- AbstractMaterialState hierarchy: State handling identical for all materials

Demonstrates Newton iteration state handling for both stateless (LinearElastic,
NoState) and stateful (PerfectPlasticity, PlasticityState) materials.
2025-11-12 00:18:16 +02:00
Jukka Aho 6b2cde6689 bench: Add comprehensive material models performance comparison
Extensive benchmark comparing new Tensors.jl approach vs old Voigt/Dict approach:

Materials tested:
- Linear Elastic (Hookean) - stateless
- Neo-Hookean Hyperelasticity - stateless (AD + manual derivatives)
- Perfect Plasticity (von Mises) - stateful with radial return

Analysis performed:
1. Type stability (@code_warntype)
2. Memory allocations (@allocated)
3. Execution time (BenchmarkTools)
4. LLVM IR inspection (inlining, vectorization)
5. Native assembly analysis

Validates key claims:
- Zero allocations for new approach (stack-only computation)
- 5-50× speedup over Voigt/Dict
- Manual derivatives outperform automatic differentiation
- Proper state handling for Newton iterations

Includes AbstractMaterial/AbstractMaterialState type hierarchy demonstration
showing how assembly code stays identical for stateless and stateful materials.
2025-11-12 00:17:30 +02:00
Jukka Aho 995f01ca9e bench: Add comprehensive linear elastic material analysis
Performs detailed performance analysis of LinearElastic material model:
1. Execution time benchmarking (@btime)
2. Memory allocation tracking (@allocated)
3. Type stability verification (@code_warntype)
4. LLVM IR inspection (inlining, vectorization)
5. Native assembly analysis (SIMD instructions)

Validates implementation quality:
- Zero allocations (stack-only computation)
- Fully inlined (no function calls in LLVM IR)
- SIMD optimized (AVX/AVX2 vector instructions)
- FMA instructions (fused multiply-add for optimal performance)

Calculates throughput (~millions of stress evaluations per second per core)
and compares actual operations against theoretical minimum FLOPs for
Hooke's law: σ = λ·tr(ε)·I + 2μ·ε
2025-11-12 00:17:08 +02:00