Commit Graph

666 Commits

Author SHA1 Message Date
Jukka Aho 77eebcc666 feat(core): Integrate modular API architecture into main JuliaFEM module
Update src/JuliaFEM.jl to include all domain api.jl files:
- Include api.jl as documentation guide (no type definitions)
- Include formulations/api.jl → export AbstractFormulation, continuum theories
- Include fields/api.jl → export Displacement, Temperature, DisplacementRotation
- Include materials/api.jl → export AbstractMaterial, compute_stress, elasticity_tensor
- Include mesh/api.jl → export AbstractMesh, node-to-elements mapping
- Include beams/shells/trusses/api.jl → export structural formulations
- Include physics.jl → export Physics, DirichletBC, NeumannBC
- Include topology/api.jl → export AbstractTopology{N}, interface functions

Proper dependency order enforced:
1. Core (api.jl documentation)
2. Formulations (HOW to discretize)
3. Fields (WHAT to solve)
4. Materials (constitutive laws)
5. Mesh (topology ownership)
6. Structural (beams/shells/trusses)
7. Physics (coupling all components)
8. Topology (element geometry)

Export statements organized by domain, immediately after each include.
Completes systematic modular API architecture integration.
2025-11-15 18:45:53 +02:00
Jukka Aho 096199af20 docs(api): Create documentation-only core API guide for modular architecture
Create src/api.jl as pure documentation (196 lines, NO type definitions):
- Documents the complete modular API architecture
- Lists all 9 domain api.jl files in dependency order
- Explains design philosophy: zero duplication, domain ownership, minimal core
- Shows type hierarchy across all domains
- Demonstrates assembly dispatch pattern (formulation × field)
- Lists 7 advantages of modular architecture

This file is the architectural guide - all actual type definitions live in
domain-specific api.jl files:
- formulations/api.jl (AbstractFormulation, continuum theories)
- fields/api.jl (Displacement, Temperature, DisplacementRotation)
- materials/api.jl (AbstractMaterial, elastic/plastic)
- mesh/api.jl (AbstractMesh, node-to-elements mapping)
- beams/shells/trusses/api.jl (structural formulations)
- topology/api.jl (AbstractTopology{N}, 17 element types)

Completes systematic modular API refactoring - every domain owns its
abstractions, core is documentation-only.
2025-11-15 18:45:06 +02:00
Jukka Aho 1b18af15a1 refactor(topology): Move interface to topology/api.jl, keep helpers in topology.jl
Refactor src/topology/topology.jl from 173 to 12 lines:
- Remove all AbstractTopology{N} interface definitions (161 lines removed)
- Remove nnodes(), dim(), reference_coordinates(), edges(), faces() stubs
- Interface now defined in src/topology/api.jl (included first)
- Keep file as placeholder for future helper functions
- Add note referencing topology/api.jl for interface

This completes separation of interface (api.jl) from implementations.
Topology/topology.jl previously mixed interface and helpers - now
clean separation following systematic modular architecture pattern.

Part of systematic modular API refactoring.
2025-11-15 18:44:48 +02:00
Jukka Aho 000dee3994 feat(physics): Add physics coupling API with multiphysics support
Create src/physics/api.jl defining physics problem abstractions:
- AbstractPhysics base type for all physics problems
- assemble!() interface for building global system (K, f)
- solve!() interface for solving physics problems
- add_dirichlet!() for essential BCs (prescribed displacements/temperatures)
- add_neumann!() for natural BCs (surface tractions/heat flux)

Physics couples four components: Mesh (where), Material (constitutive law),
Field (what we solve), Formulation (how we discretize). Physics references
Mesh (does not own it) enabling multiphysics: multiple Physics can share
one Mesh for memory efficiency and coupling.

Dispatch specialization via formulation × field type parameters:
  assemble!(::Physics{ContinuumFormulation{FullThreeD}, Displacement{3}, M, Mat})
  assemble!(::Physics{BeamFormulation{Timoshenko}, DisplacementRotation{3}, M, Mat})

Comprehensive documentation with multiphysics examples, dispatch patterns,
and interface contracts. Assembly implementations in src/assembly/.

Part of systematic modular API architecture.
2025-11-15 18:42:03 +02:00
Jukka Aho 2e41f9502d feat(topology): Add element topology API with 17 reference element types
Create src/topology/api.jl defining element topology abstractions:
- AbstractTopology{N} base type (N = node count from mesh connectivity)
- Interface: nnodes(), dim(), reference_coordinates(), edges(), faces()
- 7 shape families: Segment, Triangle, Quadrilateral, Tetrahedron, Hexahedron, Pyramid, Wedge
- 17 concrete types: Seg2/3, Tri3/6/7, Quad4/8/9, Tet4/10, Hex8/20/27, Pyr5, Wedge6/15

Key design: Topology defines SHAPE (triangle), not node count. Node count
comes from basis order: Triangle + Lagrange{Triangle,1} → 3 nodes (Tri3),
Triangle + Lagrange{Triangle,2} → 6 nodes (Tri6). This enables clean
separation: Topology (shape) ≠ Basis (interpolation) ≠ Integration (quadrature).

Reference element coordinates defined for all topologies. Zero-allocation
API using tuples. Backward compatibility: Tri3/Quad4/Tet10 aliased to
shape names with implied basis.

Comprehensive documentation with theory and examples.
Part of systematic modular API architecture.
2025-11-15 18:41:34 +02:00
Jukka Aho d9ca71febd feat(formulations): Add continuum formulation API with four theory variants
Create src/formulations/api.jl defining discretization strategy abstractions:
- AbstractFormulation base type for all formulation strategies
- AbstractContinuumTheory for continuum mechanics theory variants
- ContinuumFormulation{Theory} parameterized formulation struct
- Four concrete theories:
  * FullThreeD - Full 3D (6 stress components, no simplifications)
  * PlaneStress - Thin plates (σ_zz=0, thickness << length)
  * PlaneStrain - Thick sections (ε_zz=0, no z-variation)
  * Axisymmetric - Rotationally symmetric (σ_rr, σ_θθ, σ_zz, σ_rz)

Formulation defines HOW to discretize (math strategy), while Field defines
WHAT to solve (physical quantity). Formulation × Field determines assembly
dispatch: ContinuumFormulation{FullThreeD} + Displacement{3} dispatches to
3D solid mechanics assembly in src/assembly/continuum_3d.jl.

Comprehensive documentation with theory selection guidelines and examples.
Part of systematic modular API architecture.
2025-11-15 18:41:04 +02:00
Jukka Aho e67c888c4d feat(physics): Add concrete Physics implementation with boundary conditions
Create src/physics.jl with concrete Physics struct implementation:
- Physics{Formulation, Field, Mesh, Material} parameterized struct
- DirichletBC for essential BCs (prescribed displacements/temperatures)
- NeumannBC for natural BCs (surface tractions/heat flux)
- Constraint placeholder for future constraint handling
- Constructor with automatic type inference
- add_dirichlet!(physics, nodes, components, value) implementation
- add_neumann!(physics, surfaces, tractions) implementation

Physics references Mesh (does not own it) for memory efficiency and
multiphysics coupling. Type parameter order optimized for dispatch:
formulation × field determines assembly method specialization.

Example:
  physics = Physics(mesh, :all, Displacement{3}(),
                   ContinuumFormulation{FullThreeD}(), steel)

Uses abstract interface from src/physics/api.jl.
Part of systematic modular API architecture.
2025-11-15 18:40:47 +02:00
Jukka Aho a9dc773342 feat(mesh): Add mesh API with topology ownership and node-to-elements mapping
Create src/mesh/api.jl defining mesh-specific abstractions:
- AbstractMesh base type for all mesh structures
- nnodes_total(), nelements() for mesh sizing
- get_node(node_id) returns Vec{Dim} coordinates
- connectivity_matrix() returns element-to-nodes mapping
- get_elements_for_node(node_id) returns node-to-elements mapping (critical for nodal assembly)
- get_element_set(name), get_node_set(name) for named sets (BCs, materials, postprocessing)
- AbstractRefineStrategy, refine() for adaptive mesh refinement

Meshes own topology (coordinates, connectivity). Multiple Physics can
share one Mesh for multiphysics coupling. Node-to-elements mapping
enables nodal assembly pattern (see docs/book/multigpu_nodal_assembly.md).

Part of systematic modular API architecture.
2025-11-15 18:40:23 +02:00
Jukka Aho e9b039509c feat(fields): Add field variable API with Displacement, Temperature, and DisplacementRotation
Create src/fields/api.jl defining field-specific abstractions:
- AbstractField base type for all field variables
- Displacement{Dim} for solid mechanics (Dim DOFs per node: ux, uy, uz)
- Temperature for heat transfer (1 DOF per node: T)
- DisplacementRotation{Dim} for beams/shells (2*Dim DOFs: displacement + rotation)
- dofs_per_node() interface for DOF counting

Field type determines solution vector structure, boundary condition
interpretation, and assembly dispatch. Examples:
- Displacement{3} with ContinuumFormulation{FullThreeD} → 3D elasticity
- Temperature with ContinuumFormulation{FullThreeD} → heat transfer
- DisplacementRotation{3} with BeamFormulation → 6 DOFs (3 trans + 3 rot)

Part of systematic modular API architecture.
2025-11-15 18:40:05 +02:00
Jukka Aho 2be68f3bf3 feat(materials): Add material model API with elastic and plastic abstractions
Create src/materials/api.jl defining material-specific abstractions:
- AbstractMaterial base type for all material models
- AbstractElasticMaterial for stateless materials (no history)
- AbstractPlasticMaterial for stateful materials (history-dependent)
- compute_stress() interface (strain → stress + tangent + updated state)
- elasticity_tensor() for elastic constitutive relations

Material models use Tensors.jl (no Voigt notation). Elastic materials
are stateless (LinearElastic, NeoHookean). Plastic materials have internal
state (plastic strain εᵖ, backstress α, hardening κ, damage).

Interface returns (σ, 𝔻, state_new) where 𝔻 is the material tangent ∂σ/∂ε.

Part of systematic modular API architecture.
2025-11-15 18:39:20 +02:00
Jukka Aho 019926617c feat(shells): Add shell formulation API with Reissner-Mindlin and Kirchhoff-Love theories
Create src/shells/api.jl defining shell-specific abstractions:
- AbstractShellTheory base type for shell theories
- ReissnerMindlin concrete theory (thick shells, includes shear, h/L > 1/20, 5 DOFs)
- KirchhoffLove concrete theory (thin shells, no shear, h/L < 1/20, 3 DOFs)
- ShellFormulation{Theory} parameterized formulation struct

Reissner-Mindlin has 5 DOFs per node (ux, uy, uz, θx, θy) with explicit
rotations. Kirchhoff-Love has 3 DOFs (ux, uy, uz) with rotations computed
from displacement gradients (normals remain perpendicular).

Part of systematic modular API architecture.
2025-11-15 18:38:47 +02:00
Jukka Aho b8c769601b feat(beams): Add beam formulation API with Euler-Bernoulli and Timoshenko theories
Create src/beams/api.jl defining beam-specific abstractions:
- AbstractBeamTheory base type for beam theories
- EulerBernoulli concrete theory (classical, no shear deformation, L/h > 10)
- Timoshenko concrete theory (includes shear, thick beams)
- BeamFormulation{Theory} parameterized formulation struct

Beam elements have 6 DOFs per node (ux, uy, uz, θx, θy, θz) and work
with DisplacementRotation{3} field. Euler-Bernoulli assumes plane sections
remain perpendicular to neutral axis, while Timoshenko allows shear deformation.

Part of systematic modular API architecture.
2025-11-15 18:38:34 +02:00
Jukka Aho 30da7a3ba1 feat(trusses): Add truss formulation API with SimpleTruss theory
Create src/trusses/api.jl defining truss-specific abstractions:
- AbstractTrussTheory base type for truss theories
- SimpleTruss concrete theory (axial force only, pin-jointed)
- TrussFormulation{Theory} parameterized formulation struct

SimpleTruss supports 2D/3D displacement fields with 2 or 3 DOFs per node.
Documented for future extension with CableTruss and PretensionedTruss.

Part of systematic modular API architecture where each structural
element type owns its formulation abstractions.
2025-11-15 18:38:20 +02:00
Jukka Aho 81440d7265 refactor(topology): Remove old per-variant topology files
Remove individual topology files replaced by parametric variants.

Deleted files (16 total):
- Hexahedra: hex8.jl, hex20.jl, hex27.jl → hexahedra.jl with Hexahedron{N}
- Segments: seg2.jl, seg3.jl → segments.jl with Segment{N}
- Quadrilaterals: quad4.jl, quad8.jl, quad9.jl → quadrilaterals.jl with Quadrilateral{N}
- Triangles: tri3.jl, tri6.jl, tri7.jl → triangles.jl with Triangle{N}
- Tetrahedra: tet4.jl, tet10.jl → tetrahedra.jl with Tetrahedron{N}
- Pyramids: pyr5.jl → pyramids.jl with Pyramid{N}
- Wedges: wedge6.jl, wedge15.jl → wedges.jl with Wedge{N}

Each topology type now handles all node count variants via type parameter {N}.
Implements ADR-002 (November 13, 2025): node count from mesh connectivity.
2025-11-15 05:34:51 +02:00
Jukka Aho f980186fb6 refactor(core): Reorganize JuliaFEM.jl main module with new API structure
Major reorganization of main module file to support new architecture.

Changes - Include Order:
- Include api.jl FIRST (all abstract types and interfaces)
- Include physics.jl after api.jl (concrete Physics implementation)
- Material models after physics (LinearElastic, NeoHookean)
- New Mesh{T} infrastructure (mesh.jl, refine.jl, structured.jl)

Changes - Exports:
- Export core API types: AbstractMesh, AbstractTopology, AbstractMaterial, etc.
- Export physics types: AbstractField, AbstractFormulation, Physics, Constraint
- Export boundary conditions: DirichletBC, NeumannBC
- Export mesh operations: Mesh, topology_type, get_elements_for_node, etc.
- Export refinement: AbstractRefineStrategy, LongestEdgeBisection, refine
- Export structured mesh: create_structured_box_mesh, create_cantilever_mesh, etc.

Changes - Removals:
- Remove temporary jacobian() function (now in elements/elements.jl)
- Comment out backend files (need API updates)
- Comment out old Dict-based Mesh (conflicts with new Mesh{T})

Changes - Additions:
- Include assembly/continuum_3d.jl and continuum_3d_v2.jl
- Export compute_element_stiffness for testing

This establishes the foundation for the new type-parametric architecture.
2025-11-15 05:34:19 +02:00
Jukka Aho 9c6086a554 fix(sparse): Qualify isempty() with Base.isempty()
Fix method ambiguity by explicitly qualifying Base.isempty calls.

Changes:
- function isempty(A::SparseMatrixCOO) → function Base.isempty(A::SparseMatrixCOO)
- Internal isempty() calls qualified with Base.isempty()
- Avoids method ambiguity warnings

Consistent with assembly/problems.jl fix (commit 0d41c8c).
2025-11-15 05:33:26 +02:00
Jukka Aho 249646b740 refactor(elements): Update get_basis/get_dbasis to use new topology API
Migrate element basis evaluation functions to use new topology-aware API.

Changes:
- Add _create_topology_instance() helper to construct topology from Lagrange{T,P}
- Update get_basis() to call get_basis_functions(topology, basis, xi)
- Update get_dbasis() to call get_basis_derivatives(topology, basis, xi)
- Add jacobian() function with embedding support (1D element in 2D/3D space)
- Constraint: B <: Lagrange added to method signatures

Migration from OLD API:
- eval_basis!(B, T, xi) → get_basis_functions(topology, basis, xi)
- eval_dbasis!(B, xi) → get_basis_derivatives(topology, basis, xi)

Maintains compatibility: still returns matrices/vectors for old code interface.
2025-11-15 04:41:59 +02:00
Jukka Aho 0d41c8cc4b fix(assembly): Qualify isempty() with Base.isempty()
Fix method ambiguity by explicitly qualifying Base.isempty calls.

Changes:
- function isempty(assembly::Assembly) → function Base.isempty(assembly::Assembly)
- All internal isempty() calls qualified with Base.isempty()
- Avoids method ambiguity warnings

This is a standard Julia pattern for extending Base methods on custom types.
2025-11-15 04:21:33 +02:00
Jukka Aho 8e13862828 feat(integration): Add default_integration() helper function
Add helper to get recommended integration schemes for topology types.

Changes:
- New function: default_integration(::Type{<:AbstractTopology{N}})
- Returns appropriate Gauss{order}() for common topologies
- Rules: linear elements use minimal exact integration, quadratic use higher order
- Implementations for: Tet4/10, Hex8/20/27, Tri3/6, Quad4/8/9

Examples:
- default_integration(Hexahedron{8}) → Gauss{2}() (2×2×2 = 8 points)
- default_integration(Tetrahedron{4}) → Gauss{1}() (1 point)
- default_integration(Hexahedron{27}) → Gauss{3}() (3×3×3 = 27 points)

Simplifies user code: no need to memorize integration order for each element.
2025-11-15 04:16:43 +02:00
Jukka Aho 75735ea63c refactor(topology): Implement Wedge{N} with type parameter
Update Wedge to use node count type parameter per ADR-002.

Changes:
- struct Wedge → struct Wedge{N} <: AbstractTopology{N}
- Aliases: Wedge6 = Wedge{6}, Wedge15 = Wedge{15}
- Simplified implementation following same pattern
- Remove old design documentation

Implements ADR-002 (November 13, 2025): node count from mesh, not basis.

Old files removed: wedge6.jl, wedge15.jl
New file: Single wedges.jl handles all variants via {N}
2025-11-15 04:07:28 +02:00
Jukka Aho a9e31c1ed2 refactor(topology): Implement Pyramid{N} with type parameter
Update Pyramid to use node count type parameter per ADR-002.

Changes:
- struct Pyramid → struct Pyramid{N} <: AbstractTopology{N}
- Alias: Pyr5 = Pyramid{5}
- Simplified implementation following same pattern
- Remove old design documentation

Implements ADR-002 (November 13, 2025): node count from mesh, not basis.

Old file removed: pyr5.jl
New file: Single pyramids.jl handles all variants via {N}
2025-11-15 03:55:02 +02:00
Jukka Aho 2c6d6dc620 refactor(topology): Implement Tetrahedron{N} with type parameter
Update Tetrahedron to use node count type parameter per ADR-002.

Changes:
- struct Tetrahedron → struct Tetrahedron{N} <: AbstractTopology{N}
- Aliases: Tet4 = Tetrahedron{4}, Tet10 = Tetrahedron{10}
- Simplified implementation following same pattern
- Remove old design documentation

Implements ADR-002 (November 13, 2025): node count from mesh, not basis.

Old files removed: tet4.jl, tet10.jl
New file: Single tetrahedra.jl handles all variants via {N}
2025-11-15 02:56:52 +02:00
Jukka Aho 568f09090a refactor(topology): Implement Triangle{N} with type parameter
Update Triangle to use node count type parameter per ADR-002.

Changes:
- struct Triangle → struct Triangle{N} <: AbstractTopology{N}
- Aliases: Tri3 = Triangle{3}, Tri6 = Triangle{6}, Tri7 = Triangle{7}, Tri10 = Triangle{10}
- Simplified implementation following same pattern
- Remove old design documentation

Implements ADR-002 (November 13, 2025): node count from mesh, not basis.

Old files removed: tri3.jl, tri6.jl, tri7.jl
New file: Single triangles.jl handles all variants via {N}
2025-11-15 02:47:04 +02:00
Jukka Aho 4bf21edda8 refactor(topology): Implement Quadrilateral{N} with type parameter
Update Quadrilateral to use node count type parameter per ADR-002.

Changes:
- struct Quadrilateral → struct Quadrilateral{N} <: AbstractTopology{N}
- Aliases: Quad4 = Quadrilateral{4}, Quad8 = Quadrilateral{8}, Quad9 = Quadrilateral{9}
- Simplified implementation following same pattern as Hexahedron and Segment
- Remove 140+ lines of old design documentation

Implements ADR-002 (November 13, 2025): node count from mesh, not basis.

Old files removed: quad4.jl, quad8.jl, quad9.jl
New file: Single quadrilaterals.jl handles all variants via {N}
2025-11-15 02:29:36 +02:00
Jukka Aho be550320b5 refactor(topology): Implement Segment{N} with type parameter
Update Segment to use node count type parameter per ADR-002.

Changes:
- struct Segment → struct Segment{N} <: AbstractTopology{N}
- Aliases: Seg2 = Segment{2}, Seg3 = Segment{3}
- Add nnodes(), dim() implementations
- reference_coordinates() for Segment{2} and Segment{3}
- Generic edges() and faces() for any N
- Remove 100+ lines of old design documentation

Implements ADR-002 (November 13, 2025): node count from mesh, not basis.

Old files removed: seg2.jl, seg3.jl
New file: Single segments.jl handles all variants via {N}
2025-11-15 02:27:02 +02:00
Jukka Aho 4c49570cec refactor(topology): Implement Hexahedron{N} with type parameter
Update Hexahedron to use node count type parameter per ADR-002.

Changes:
- struct Hexahedron → struct Hexahedron{N} <: AbstractTopology{N}
- Aliases now specify node count: Hex8 = Hexahedron{8}
- Add nnodes() implementation: returns N from type parameter
- Simplify documentation: remove 150+ lines explaining old design
- Keep reference_coordinates() for Hexahedron{8} only
- Generic edges() and faces() work for any N

Benefits:
- Type system encodes node count (compile-time)
- Hex8, Hex20, Hex27 are distinct types (better dispatch)
- Matches mesh file reality (mesh specifies node count)
- Implements ADR-002 decision (November 13, 2025)

Old files removed: hex8.jl, hex20.jl, hex27.jl (separate files)
New file: Single hexahedra.jl handles all variants via {N}
2025-11-15 02:24:53 +02:00
Jukka Aho b2d25e9491 refactor(topology): Add node count type parameter to AbstractTopology
Change AbstractTopology to AbstractTopology{N} where N is node count.

This implements ADR-002 (November 13, 2025) decision: node count comes
from mesh connectivity and should be captured in the type for
compile-time optimization.

Benefits:
- Enables Val(N) for zero-allocation ntuple operations
- Allows loop unrolling for small N (8, 20, 27 nodes typical)
- Type-stable operations based on node count
- Node count known from mesh before basis selection

Documentation updates:
- Add Type Parameter section with examples
- Add Rationale section explaining performance benefits
- Reference ADR-002 for design decision details

Concrete types updated in subsequent commits:
  Hexahedron{N}, Tetrahedron{N}, Triangle{N}, etc.
2025-11-15 02:24:01 +02:00
Jukka Aho 36e0a5fd51 refactor(basis): Update generator to remove OLD API functions
Update src/basis/lagrange_generator.jl to stop generating deprecated

Changes:
- Remove code generation for eval_basis!() (4 function variants)
- Remove code generation for eval_dbasis!() (2 function variants)
- Rename parameter: topology_type::Symbol → topology_type_expr (clearer)
- Update comments: "Generate code for NEW API only"
- Keep NEW API: get_basis_functions(), get_basis_derivatives()

This generator produces src/basis/lagrange_generated.jl (already
committed with updated output).

The OLD API is no longer needed - all code uses NEW API with
Topology + Basis separation architecture.
2025-11-15 02:19:26 +02:00
Jukka Aho 5248f6e470 chore(basis): Regenerate Lagrange basis functions (remove old API)
Regenerate src/basis/lagrange_generated.jl with updated generator.

Changes:
- Remove deprecated eval_basis!() and eval_dbasis!() functions (OLD API)
- Keep NEW API: get_basis_functions() and get_basis_derivatives()
- Add node count to element comments (e.g., "Seg2, 2 nodes")
- Update generation timestamp: 2025-11-13 02:42:16

This is auto-generated code from src/basis/lagrange_generator.jl.
The old API functions are no longer needed as all code now uses
the NEW API (Topology + Basis separation).

Generated: 594 line changes across all 15 Lagrange element types
(Seg2, Seg3, Tri3, Tri6, Tri7, Quad4, Quad8, Quad9, Tet4, Tet10,
Hex8, Hex20, Hex27, Wedge6, Wedge15).
2025-11-15 02:18:27 +02:00
Jukka Aho 5ee4f2d86b feat(materials): Add elasticity_tensor() for LinearElastic
Add elasticity_tensor(material::LinearElastic) function that returns
the 4th-order elasticity tensor C_{ijkl} for assembly.

Formula: C_{ijkl} = λ δ_{ij} δ_{kl} + μ (δ_{ik} δ_{jl} + δ_{il} δ_{jk})

Returns Tensor{4,3,Float64} for direct use in stiffness assembly:
  K_ij^{αβ} = ∫ (∂N_i/∂x_γ) C_{αβγδ} (∂N_j/∂x_δ) dV

This eliminates need for Voigt notation and B-matrices in assembly,
enabling pure tensor mathematics (Tensors.jl).

Used by CPU backend (src/backend/cpu.jl) in compute_element_stiffness().
Foundation for GPU implementation (same tensor approach).
2025-11-15 02:17:00 +02:00
Jukka Aho 6722716ac3 refactor(materials): Move abstract types to api.jl for include order
Comment out AbstractMaterial, AbstractElasticMaterial, and
AbstractPlasticMaterial definitions in abstract_material.jl.

These types are now defined in src/api.jl which is included first,
avoiding forward reference and circular dependency issues.

Documentation and concrete implementations remain in this file.

This fixes include order problems where materials needed to be defined
before physics_api.jl but physics_api.jl needed the abstract types.
2025-11-15 02:16:23 +02:00
Jukka Aho 9b22df8d3c refactor(physics): Implement double-dispatch architecture
Major API refactoring: replace mutable ElasticityPhysicsType with
type-parametric Physics struct for compile-time dispatch.

New type hierarchy:
- AbstractField: What we solve (Displacement{3}, Temperature, etc.)
- AbstractFormulation: How we discretize (ContinuumFormulation, BeamFormulation)
- AbstractMaterial: Material behavior (LinearElastic, NeoHookean)
- AbstractMesh: Mesh container

Physics{Formulation, Field, Mesh, Material} enables natural dispatch:
  assemble(::Physics{ContinuumFormulation{FullThreeD}, Displacement{3}, M, Mat})
  assemble(::Physics{BeamFormulation{Timoshenko}, DisplacementRotation{3}, M, Mat})

Type parameter order prioritizes Formulation for dispatch hierarchy.

Breaking changes:
- Old: Physics(Elasticity, "name", 3)
- New: Physics(name=..., mesh=..., field=Displacement{3}(),
               formulation=ContinuumFormulation{FullThreeD}(), material=...)
- Deprecate: add_elements!() - Physics references Mesh, doesn't own elements

Benefits:
- Type stability: All types known at compile time
- Dispatch: Specialized methods for formulation/field combinations
- Extensibility: New formulations/fields without modifying core
- Performance: No runtime type checks, optimal codegen

This is foundation for the NEW API (TDD tests, Nov 14 2025).
2025-11-14 23:22:42 +02:00
Jukka Aho b485886324 fix(integration): Resolve IntegrationPoint name conflict
Add alias IntegrationPointNEW to capture NEW API type before it's
shadowed by legacy core_types.jl definitions.

Update integration_points() to explicitly use IntegrationPointNEW{D}
with dimension parameter, avoiding ambiguity between old and new API
types.

This is a temporary workaround during the old→new API migration phase.
Once legacy code is removed, IntegrationPoint will be the canonical type.
2025-11-14 23:16:48 +02:00
Jukka Aho 0ca159972e feat(backend): Complete tensor-based stiffness computation
Implement full 4th-order elasticity tensor approach in CPU backend:

- Fix topology extraction: extract_topology_type() returns type, then
  instantiate with node count N (was causing crashes)

- Implement basis derivative evaluation: get_basis_derivatives() call
  now works (BLOCKER resolved)

- Complete Jacobian transformation: J = ∑ X_k ⊗ dN_k/dξ using proper
  tensor outer products (Tensors.jl)

- Implement stiffness assembly: K_ij^{αβ} = ∫ (∂N_i/∂x_γ) C_{αβγδ}
  (∂N_j/∂x_δ) detJ dξ with double contractions

- Add basevec() helper for constructing unit vectors

NO B-matrix, NO Voigt notation - pure tensor mathematics following
golden standard (docs/src/book/multigpu_nodal_assembly.md).

This is the foundation for GPU implementation (same math, different backend).
2025-11-14 21:55:22 +02:00
Jukka Aho c40fcdbb91 feat(geometry): Add strain computation function
- Implement compute_strain() for small strain tensor calculation
- Zero allocation with NTuple inputs and Tensors.jl
- Type stable (@inferred passes)
- Complete test suite with 4 test cases (uniaxial, shear, rigid body, performance)
- Performance validated: 0 allocations, ~110ns median
- Add to test suite in runtests.jl
- Export from JuliaFEM module

Resolves user story #0001
2025-11-12 02:19:45 +02:00
Jukka Aho d38a800203 refactor(solvers): Remove push! and fix formatting
- Replace push!(solver.problems, ...) with add_problems!(solver, ...)
- Remove push!(solver, problem) - violated Julia semantics
- Fix spacing in matrix operations (K[I,I] → K[I, I])
- Consistent spacing around operators
- No functional changes to solver logic
2025-11-12 01:11:39 +02:00
Jukka Aho ce8960395f refactor(dirichlet): Simplify initialization check for Dirichlet BCs
- Remove unnecessary initialization for Dirichlet problems
- Dirichlet BCs don't require unknown field (optional)
- Assembly checks haskey() before processing elements
- Fix spacing and formatting (Dict{K,V}, for i=1:n)
- Update comments to explain optional field behavior
2025-11-12 01:11:18 +02:00
Jukka Aho 09aa79b4b0 style(assembly): Fix formatting in problems.jl
- Consistent spacing in type annotations (Dict{K,V} not Dict{K, V})
- Align struct field declarations
- Fix spacing around operators and function calls
- Consistent lambda function formatting
- No functional changes, pure style cleanup
2025-11-12 01:11:04 +02:00
Jukka Aho 3127572b50 refactor(deprecated): Update for immutable Element architecture
- update!() now throws helpful error with migration instructions
- Explains immutable elements: use update() returning new element
- length(element) uses connectivity instead of properties
- size(element) returns (dimension, nnodes) tuple
- Provides OLD vs NEW API examples in error message
- References migration guide documentation
2025-11-12 01:10:52 +02:00
Jukka Aho 68721ce283 docs(basis): Document deprecated and new basis function APIs
- Mark eval_basis!() and eval_dbasis!() as DEPRECATED
- Document why deprecated: topology/basis separation, unclear naming
- Add docstrings for get_basis_functions() and get_basis_derivatives()
- Provide migration examples: OLD vs NEW API side-by-side
- Reference basis_api.jl for full documentation
- Explain topology and basis should be passed separately
2025-11-12 01:10:36 +02:00
Jukka Aho b6f9cd3130 refactor(elements): Update integration points to use new API
- get_integration_points_from_basis() maps Lagrange types to Gauss quadrature
- get_base_topology() maps deprecated names to base topology (Tri6→Triangle)
- Use get_gauss_points!() for zero-allocation integration
- Fix interpolate() to handle both AbstractField and raw data
- Fix Jacobian computation: preserve connectivity order in Dict→Vec conversion
- Support order parameter for increased quadrature accuracy
- Gauss orders 1-5 supported for all topologies
2025-11-12 01:10:22 +02:00
Jukka Aho 3ee3125991 refactor(core): Modernize JuliaFEM.jl module with new architecture
- Update module docstring: contact mechanics focus, GPU acceleration
- Modern API examples: Physics{Elasticity}, immutable Elements
- Separation of concerns: topology, integration, basis, materials
- Export topology types (Segment, Triangle, Quadrilateral, etc.)
- Export deprecated aliases (Tri3→Triangle, Quad4→Quadrilateral)
- Include new modules: geometry/, physics_api.jl, backend/
- Include assembly structures: element and nodal
- CUDA extension support (loaded automatically with 'using CUDA')
- Document nodal assembly architecture and benefits
2025-11-12 01:09:36 +02:00
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