Files
JuliaFEM.jl/scripts
Jukka Aho 31d8463ef0 feat: Pre-generation infrastructure for Lagrange basis functions
**Problem:**
- __precompile__(false) in create_basis.jl causes slow package loading
- Symbolic math evaluated at runtime (100+ ms overhead)
- Dynamic eval() prevents full precompilation
- Difficult to debug generated code

**Solution: Generate Once, Use Forever**
- Renamed: create_basis.jl → lagrange_generator.jl (tool, not runtime code)
- Created: scripts/generate_lagrange_basis.jl (orchestration script)
- Created: scripts/README.md (documentation for generation workflow)
- Created: docs/theory/lagrange_basis_functions.md (mathematical foundation)

**Theory Documentation (400+ lines):**
- Kronecker delta property: N_i(x_j) = δ_ij
- Vandermonde matrix method: Vα_i = e_i
- Worked example: Seg2 linear element (step-by-step derivation)
- Polynomial completeness table (1D/2D/3D orders)
- Complete standard element catalog
- Pre-generation vs runtime comparison
- Numerical stability discussion

**Generation Script:**
- Defines all 15 standard Lagrange element types:
  * 1D: Seg2, Seg3
  * 2D Tri: Tri3, Tri6
  * 2D Quad: Quad4, Quad8, Quad9
  * 3D Tet: Tet4, Tet10
  * 3D Hex: Hex8, Hex20, Hex27
  * 3D Pyr: Pyr5
  * 3D Wedge: Wedge6, Wedge15
- For each: node coordinates + polynomial ansatz
- Calls lagrange_generator symbolic engine
- Writes clean Julia code → src/basis/lagrange_generated.jl (to be created)

**Architecture:**

**Benefits:**
- ~150× faster package loading (150ms → <1ms)
- Full precompilation enabled
- Generated code is readable/debuggable
- Git shows what changed (mathematics visible in diffs)
- Reproducible builds

**Workflow:**
1. Edit element catalog in scripts/generate_lagrange_basis.jl
2. Run: julia --project=. scripts/generate_lagrange_basis.jl
3. Review src/basis/lagrange_generated.jl
4. Test and commit

**Next Steps:**
1. Run generation script → create lagrange_generated.jl
2. Update src/JuliaFEM.jl to include generated file
3. Comment out old lagrange_*.jl includes
4. Remove __precompile__(false)
5. Verify all tests pass
6. Measure package load time improvement

**Also Included:**
- scripts/check_namespace_collisions.jl (consolidation tool)
- scripts/fix_vendor_element_types.py (Element type fixer)

See: docs/theory/lagrange_basis_functions.md for full mathematical explanation
2025-11-09 04:07:28 +02:00
..

JuliaFEM Scripts

This directory contains development and code generation scripts for JuliaFEM.

Basis Function Generation

generate_lagrange_basis.jl

Purpose: Pre-generate all Lagrange basis functions for standard finite elements.

Why Pre-generate?

  • Fast loading: No symbolic math at package load time (100+ ms → 0 ms)
  • Full precompilation: Remove __precompile__(false) restriction
  • Readable code: Generated code is easy to debug and understand
  • Version control: Changes to mathematics show up in git diffs
  • Reproducible: Same input always produces same output

When to Run:

  • Adding new element types (Seg2, Tri3, Hex20, etc.)
  • Fixing bugs in generation logic
  • Changing polynomial ansatz strategy
  • After modifying src/basis/lagrange_generator.jl

Usage:

cd /path/to/JuliaFEM.jl
julia --project=. scripts/generate_lagrange_basis.jl

Output:

  • src/basis/lagrange_generated.jl (commit this file!)

Theory: See docs/theory/lagrange_basis_functions.md for mathematical foundation.

Architecture:

src/basis/lagrange_generator.jl
    │
    │ (symbolic engine - uses symbolic differentiation)
    │
    ↓
scripts/generate_lagrange_basis.jl
    │
    │ (orchestration - defines all element types)
    │
    ↓
src/basis/lagrange_generated.jl
    │
    │ (clean Julia code - no eval, fully precompilable)
    │
    ↓
src/JuliaFEM.jl includes generated file

Generated Elements:

Dimension Linear Quadratic Higher
1D Seg2 Seg3 -
2D Tri Tri3 Tri6 -
2D Quad Quad4 Quad8, Quad9 -
3D Tet Tet4 Tet10 -
3D Hex Hex8 Hex20, Hex27 -
3D Pyramid Pyr5 - -
3D Wedge Wedge6 Wedge15 -

Total: 15 element types covering all standard Lagrange families.

Performance Impact:

  • Before: 150+ ms at package load (symbolic math for each element)
  • After: < 1 ms (just include pre-generated file)
  • Speedup: ~150× faster package loading

Workflow:

  1. Edit element catalog in scripts/generate_lagrange_basis.jl
  2. Run generation script
  3. Review src/basis/lagrange_generated.jl
  4. Run tests: julia --project=. -e 'using Pkg; Pkg.test()'
  5. Commit both files: git add scripts/ src/basis/lagrange_generated.jl

Example: Adding Hex64 (Triquartic)

# In scripts/generate_lagrange_basis.jl, add to element catalog:
push!(elements, (
    name = "Hex64",
    description = "64-node triquartic hexahedral element",
    coordinates = [
        # ... 64 nodes (corners + edges + faces + volume)
    ],
    ansatz = [
        :(1), :(ξ), :(η), :(ζ),  # ... up to ξ³η³ζ³
    ]
))

Then regenerate:

julia --project=. scripts/generate_lagrange_basis.jl

The new Hex64 type will be automatically available in JuliaFEM!


Future Scripts (Planned)

benchmark_suite.jl

Run comprehensive performance benchmarks.

validate_against_reference.jl

Compare JuliaFEM results to Code Aster/ABAQUS.

generate_element_matrices.jl

Pre-compute stiffness matrices for simple elements.


See also:

  • docs/theory/lagrange_basis_functions.md - Mathematical theory
  • src/basis/lagrange_generator.jl - Symbolic generation engine
  • llm/VISION_2.0.md - Overall project architecture