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.
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}
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}
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}
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}
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}
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}
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}
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.
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.)
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
- 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)
- 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)
- 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)
- 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)
- Changed struct name from Seg2 to Segment
- Removed nnodes() method (node count now determined by basis)
- Updated all function signatures to use Segment instead of Seg2
- Added Seg2 as backwards compatibility alias
- Added note explaining basis determines node count
- Changed struct name from Quad4 to Quadrilateral
- Removed nnodes() method (node count now determined by basis)
- Updated documentation to explain topology vs basis separation
- Added examples showing Lagrange and Serendipity differences
- Added Quad4 as deprecated alias for backwards compatibility
- Clarified that topology defines geometry only, basis determines nodes
- Changed struct name from Tri3 to Triangle
- Removed nnodes() method (node count now determined by basis)
- Updated documentation to explain topology vs basis separation
- Added examples showing Lagrange{Triangle, P} for different degrees
- Added Tri3 as deprecated alias for backwards compatibility
- Clarified that topology defines geometry only, basis determines nodes