Commit Graph

624 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 269fa9a4ad feat(basis): Add dual-API basis function support (modern + legacy)
- New API: get_basis_functions() returns tuple of functions
- New API: get_basis_derivatives() returns tuple of gradient functions
- basis_api.jl: 210 lines implementing modern functional API
- Re-generated lagrange_generated.jl with 242 new lines
- abstract.jl: Add nnodes() method for Lagrange type
- Backward compatible: old eval_basis! API unchanged
- See ADR-003 for design rationale
2025-11-10 22:26:23 +02:00
Jukka Aho 30ca3de56a feat(elements): Add immutable update() function for elements
- Implement update() that returns new element (immutable pattern)
- Supports keyword arguments for ergonomic field updates
- Preserves backward compatibility with update!() (legacy)
- Dual-API approach: modern immutable + legacy mutable both supported
- 82 lines including documentation and examples
- See docs/book/fundamentals_element_creation.md for usage guide
2025-11-10 22:25:59 +02:00
Jukka Aho 7ffecf73e7 refactor(core): Update JuliaFEM.jl exports for new APIs
- Add new basis API exports: get_basis_functions, get_basis_derivatives
- Export both update() (immutable) and update!() (legacy)
- Re-enable assemble! and postprocess! exports
- Document new basis API with ADR-003 reference
- Include basis_api.jl for dual-API support (modern + legacy)
2025-11-10 22:25:41 +02:00
Jukka Aho c3ba765447 feat(gpu): Add complete GPU-resident elasticity solver
- Implement ElasticityPhysics struct with nodal assembly
- Two-phase assembly: element contributions then nodal accumulation
- Matrix-free CG solver using IterativeSolvers.jl
- Support for pressure boundary conditions
- Complete test: 190 nodes, 434 elements, converges in 430 iterations
- Max displacement 4.1 cm (cantilever beam validation)
- 476 lines including full documentation
2025-11-10 22:24:23 +02:00
Jukka Aho a332d79736 fix(elements): Update Poi1 to non-parametric AbstractBasis
Changes to src/elements/elements_lagrange.jl:
- Changed Poi1 from AbstractBasis{0} to AbstractBasis (non-parametric)
- Added nnodes(::Type{Poi1}) = 1 method
- Added nnodes(::Poi1) = 1 instance method
- Added comment explaining Poi1 as 0D point element
- Resolves type parameter mismatch with new AbstractBasis definition
2025-11-09 21:03:39 +02:00
Jukka Aho a6c692d074 refactor(core): Uncomment Dirichlet, aster_read_mesh, and lagrange elements
Changes to src/JuliaFEM.jl:
- Uncommented problems_dirichlet.jl include and Dirichlet export (lines 288-289)
- Uncommented elements_lagrange.jl include (line 261)
- Uncommented aster_read_mesh export (line 340)
- Fixed indentation in jacobian function (spaces → consistent spacing)
- Fixed spacing in J_data array indexing (J_data[i,j] → J_data[i, j])

Purpose: Enable more problem types and mesh readers for testing
2025-11-09 21:03:12 +02:00
Jukka Aho aab8b7d6ce feat(test): First test rewritten for immutable elements (test_elasticity_1d)
Rewrote test_elasticity_1d.jl to follow immutable element pattern.
This is the first fully working test with the new architecture!

Changes:
1. test/test_elasticity_1d.jl:
   - Convert Dict node data to element-local tuple format
   - Wrap data in DVTI field objects (Discrete, Variable, Time-Invariant)
   - Create element with fields at construction: Element(Seg2, conn; fields=(...))
   - Fix Jacobian shape expectation (3×1 not 1×3 for 1D in 3D)

2. src/JuliaFEM.jl:
   - Add minimal jacobian() function for AbstractBasis (non-parametric)
   - Handles embedding (1D element in 3D space) correctly
   - Returns Matrix instead of Tensor for flexibility

3. src/elements/elements.jl:
   - Fix Jacobian computation to handle both Tuple and IntegrationPoint
   - Fix detJ calculation logic for embedded elements (check m not size(JT,2))
   - Correctly handle 1D elements: detJ = ||∂X/∂ξ||

Result: test_elasticity_1d.jl passes! ✓

This validates the immutable architecture:
- Element created with fields at construction
- No mutation needed during test
- Field system integration working (DVTI fields)
- Jacobian computation working for embedded elements
2025-11-09 18:42:56 +02:00
Jukka Aho 41e09b2c92 feat(compat): Add compatibility shim for old mutable field API
Implements compatibility layer to allow old test code to run with new
immutable element design (though fields won't actually update).

src/elements/elements.jl:
- Replaced has_dfield/get_dfield to work with new fields API
- Fixed get_sfield/get_dfield to handle empty Tuple{} fields
- All dfield functions now map to element.fields (immutable NamedTuple)

src/topology/*.jl (seg2, tri3, quad4, tet4, hex8):
- Added nnodes() implementation for each topology type
- Returns corner node count (backwards compatibility)
- Example: nnodes(::Triangle) = 3, nnodes(::Hexahedron) = 8
- Note: Actual node count depends on basis degree in new architecture

Test Results:
- test_topology_standalone.jl: 36/36 tests passing ✓
- Full test suite: 43 errors (same as before)
- Error breakdown:
  * 40+ tests: Problem types not defined (Elasticity, Heat, Mortar)
  * 2 tests: Mesh readers not defined (aster_read_mesh)
  * 1 test: Tries to mutate empty element (test_elasticity_1d)

Next Steps:
- Tests that create empty elements then mutate need rewriting
- Pattern: Element(Seg2, (1,2)) + update!() → not compatible
- New pattern: Element(..., fields=(geometry=X, displacement=u))
- See docs/design/IMMUTABILITY.md for migration guide
2025-11-09 18:08:39 +02:00
Jukka Aho 7ed8d003c6 style(basis): Clean up whitespace in lagrange_generator.jl
- Remove trailing whitespace
- Fix spacing in Dict type annotation: Dict{String, Tuple{...}} → Dict{String,Tuple{...}}

No functional changes.
2025-11-09 17:36:30 +02:00
Jukka Aho 41b8a4c98c feat(basis): Enable Lagrange{T,P} basis functions in main module
- Uncommented include for lagrange_generated.jl
- Added exports: AbstractBasis, Lagrange, Serendipity
- Updated comments to reflect new parametric architecture

Package now loads successfully with new basis system.
All 15 element types available:
  Lagrange{Segment, 1}, Lagrange{Segment, 2}
  Lagrange{Triangle, 1}, Lagrange{Triangle, 2}
  Lagrange{Quadrilateral, 1}, Lagrange{Quadrilateral, 2} (×2 variants)
  Lagrange{Tetrahedron, 1}, Lagrange{Tetrahedron, 2}
  Lagrange{Hexahedron, 1}, Lagrange{Hexahedron, 2} (×2 variants)
  Lagrange{Pyramid, 1}
  Lagrange{Wedge, 1}, Lagrange{Wedge, 2}
2025-11-09 17:30:37 +02:00
Jukka Aho 4f8f85c895 chore(basis): Regenerate basis functions for Lagrange{T,P} architecture
Generated by: julia --project=. src/basis/lagrange_generator.jl

Changes:
- All 15 element types now use Lagrange{T,P} parametric type
- Functions: get_reference_element_coordinates(), eval_basis!(), eval_dbasis!()
- Reference coordinates now return tuples (zero-allocation)
- Removed old Seg2Basis, Tri3Basis, Quad4Basis, etc. struct definitions
- All methods work with both Type{Lagrange{T,P}} and Lagrange{T,P} instances

Validated:
- Triangle: Kronecker delta property holds (N_i(x_j) = δ_ij)
- Quadrilateral, Tetrahedron, Hexahedron: First node evaluates to (1,0,0,...)
- Derivatives: Correct gradients at reference coordinates
2025-11-09 17:30:07 +02:00
Jukka Aho 6fd99fa323 feat(basis): Update generator for parametric Lagrange{T,P} architecture
- Changed create_basis() signature from (name, desc, X, ...) to (topology_type, poly_degree, desc, X, ...)
- Generator now produces methods for Lagrange{Segment,1}, Lagrange{Triangle,1}, etc.
- Added ELEMENT_TO_LAGRANGE mapping dict (old names → topology_type + poly_degree)
- Fixed reference coordinates to return tuples instead of vectors
- Removed struct definitions (now use parametric Lagrange{T,P} type)
- Removed Base.size(), Base.length() methods (use nnodes() instead)
- Fixed typo: 'antsatz' → 'ansatz'

All 15 element types regenerate successfully:
  Segment (1,2), Triangle (1,2), Quadrilateral (1,2,2), Tetrahedron (1,2),
  Hexahedron (1,2,2), Pyramid (1), Wedge (1,2)

Tests pass for all element types.
2025-11-09 17:29:35 +02:00
Jukka Aho 626cc49780 refactor: Comment out old basis and problem files incompatible with new API
Commented out files using AbstractBasis{dim}:
- basis/lagrange_generated.jl (449 lines, uses AbstractBasis{1/2/3})
- basis/nurbs_segment.jl (NSeg <: AbstractBasis{1})
- basis/nurbs_surface.jl (NSurf <: AbstractBasis{2})
- basis/nurbs_solid.jl (NSolid <: AbstractBasis{3})
- basis/math.jl (jacobian, grad functions use AbstractBasis{dim})
- elements/elements_lagrange.jl (Poi1 <: AbstractBasis{0})
- elements/integrate.jl (references NSeg, Poi1, old basis types)

Commented out problem files using old Element API:
- problems_heat.jl (uses Seg2, Tri3, Quad4, element.sfields)
- problems_truss.jl (uses Seg2, Poi1, element.sfields)
- problems_elasticity.jl (uses old element types, element.sfields)
- problems_dirichlet.jl (uses old API)
- problems_mortar.jl (uses old API)
- problems_mortar_3d.jl (uses old API)

Status after this commit:
- Package loads successfully ✓
- ~70% of functionality removed (intentional)
- All 43 tests fail (expected - old API incompatible)
- Next: Regenerate basis functions for Lagrange{T,P}
- Then: Rewrite math.jl, integrate.jl, rebuild problems

Rationale: Clean break from old Dict-based, type-unstable architecture.
New GPU-ready Element requires complete rebuild of dependent code.
2025-11-09 17:09:48 +02:00
Jukka Aho f89d48a112 refactor(deprecated): Remove old getproperty redirection for new Element API
- Comment out Base.getproperty(element::Element, :fields) redirection
- Old code redirected element.fields → element.dfields (Dict-based fields)
- New Element has fields::F directly (type-stable NamedTuple or struct)
- No redirection needed with new architecture
- Rationale: New Element{N,NIP,F,B} has fields as direct struct member
2025-11-09 17:09:27 +02:00
Jukka Aho 782e559d4b refactor(basis): Non-parametric AbstractBasis for dynamic topology dimensions
- Change AbstractBasis{dim} to AbstractBasis (remove dimension type parameter)
- Enable Lagrange{T,P} <: AbstractBasis inheritance (T=topology, P=polynomial degree)
- Replace interface: length/size → nnodes/ndims
- Remove allocating wrappers: eval_basis(), eval_dbasis()
- Add nnodes() for both Lagrange instances and types
- Implement nnodes formulas for all topologies:
  * Segment: P+1
  * Triangle: (P+1)(P+2)/2
  * Quadrilateral: (P+1)²
  * Tetrahedron: (P+1)(P+2)(P+3)/6
  * Hexahedron: (P+1)³
  * Pyramid: hardcoded (5, 13, 29)
  * Wedge: (P+1)²(P+2)/2
- Add nnodes() for old topology names (Tri3, Quad4, etc.) for backwards compatibility
- BREAKING: All AbstractBasis{dim} code incompatible
- Rationale: Lagrange dimension comes from topology at runtime, not compile-time constant
2025-11-09 17:09:11 +02:00
Jukka Aho 7a23faf17d refactor(elements): GPU-ready Element with type-stable fields::F parameter
- Replace AbstractElement{M,B} with AbstractElement{F,B} (F=fields type)
- Replace Element struct: remove dfields Dict, sfields M, properties B
- Add Element struct: id, connectivity NTuple, integration_points NTuple, fields::F, basis::B
- Field container F is type-stable (NamedTuple, struct, or empty tuple)
- Immutable connectivity and fields (GPU-compatible, zero-allocation)
- Add Element(basis_type, connectivity; fields=(), id=0) constructor
- Add Element(topology_type, connectivity; kwargs...) convenience constructors
- Add infer_lagrange_order(topology, n_nodes) to auto-detect polynomial degree
- Support all 17 topologies: Segment, Triangle, Quad, Tet, Hex, Pyramid, Wedge
- Comment out element_info!() function (used BasisInfo from commented-out math.jl)
- BREAKING: Completely new Element API with type-stable fields
- GPU-ready: el.fields.E returns Float64 (compile-time known type)
2025-11-09 17:08:36 +02:00
Jukka Aho 3cf39bb14d refactor(assembly): Comment out Tet10 specialization, fix formatting
- Commented out assemble_mass_matrix! specialization for Element{Tet10}
- Tet10 is now a topology type, not a basis type (name conflict)
- Needs refactoring to use Tet10Basis or new parametric architecture
- Fixed code formatting (spacing around operators, indentation)
- Added TODO comment explaining the issue
2025-11-09 09:29:30 +02:00
Jukka Aho 05febfc938 refactor(exports): Update topology exports for new architecture
- Removed nnodes from topology exports (now in basis module)
- Added exports for new topology names (Triangle, Quadrilateral, etc.)
- Kept old names as exports (they're aliases for backwards compatibility)
- Added explanatory comments about topology vs basis separation
- Added examples showing how node count comes from basis now
- Organized exports by dimension (0D/1D/2D/3D)
2025-11-09 09:29:19 +02:00
Jukka Aho abdbcb37cc refactor(elements): Comment out old topology_to_basis shims
- Commented out topology_to_basis() helper and old Element constructors
- These mapped old names (Tri3→Tri3Basis) which no longer exist
- Need to update for new Lagrange{Topology, P} parametric architecture
- Added TODO comment explaining migration needed
- Temporary measure until new Element constructors are implemented
2025-11-09 09:29:06 +02:00
Jukka Aho 9f42575cf2 feat(basis): Add Lagrange{Topology, P} parametric basis type
- Added Lagrange{T<:AbstractTopology, P} struct for parametric basis
- Implemented nnodes() formulas for all 7 topologies:
  - Segment: P+1 nodes
  - Triangle: (P+1)(P+2)/2 nodes (simplex formula)
  - Quadrilateral: (P+1)² nodes (tensor product)
  - Tetrahedron: (P+1)(P+2)(P+3)/6 nodes (simplex formula)
  - Hexahedron: (P+1)³ nodes (tensor product)
  - Pyramid: hardcoded for P=1,2,3 (no simple formula)
  - Wedge: (P+1)²(P+2)/2 nodes (triangle × segment)
- Added comprehensive documentation with examples
- Exported Lagrange and nnodes
- Node count now comes from basis, not topology
2025-11-09 09:28:45 +02:00
Jukka Aho dcc7f69a75 refactor(topology): Rename Wedge6 to Wedge, remove hardcoded node count
- Changed struct name from Wedge6 to Wedge
- Removed nnodes() method (node count now determined by basis)
- Updated all function signatures to use Wedge
- Added Wedge6 as backwards compatibility alias
- Added note explaining basis determines node count (P1=6, P2=15 nodes)
2025-11-09 09:28:29 +02:00
Jukka Aho ca7c8a4c75 refactor(topology): Rename Pyr5 to Pyramid, remove hardcoded node count
- Changed struct name from Pyr5 to Pyramid
- Removed nnodes() method (node count now determined by basis)
- Updated all function signatures to use Pyramid
- Added Pyr5 as backwards compatibility alias
- Added note explaining basis determines node count (P1=5, P2=13, P3=29)
2025-11-09 09:28:17 +02:00
Jukka Aho 835aac9962 refactor(topology): Rename Hex8 to Hexahedron, remove hardcoded node count
- Changed struct name from Hex8 to Hexahedron
- Removed nnodes() method (node count now determined by basis)
- Updated all function signatures to use Hexahedron
- Added Hex8 as backwards compatibility alias
- Added note explaining basis determines node count (Q1=8, Q2=27 nodes)
2025-11-09 09:28:07 +02:00
Jukka Aho 260ea0b170 refactor(topology): Rename Tet4 to Tetrahedron, remove hardcoded node count
- Changed struct name from Tet4 to Tetrahedron
- Removed nnodes() method (node count now determined by basis)
- Updated all function signatures to use Tetrahedron
- Added Tet4 as backwards compatibility alias
- Added note explaining basis determines node count (P1=4, P2=10 nodes)
2025-11-09 09:27:54 +02:00