Skip to content

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 26 Jun 13:32
3275d6f

0.11.0 (2026-06-26)

This release simplifies and unifies the sparsity pattern generation API across the codebase. It introduces automatic JAX-trace-based sparsity detection directly from energy and virtual work formulations, moves sparsity generation logic out of the Compound class, and consolidates sparsity augmentation/reduction under the Lifter class.

Breaking Changes

  • Removed/Deprecated Sparse APIs: The following helper functions have been removed from tatva.sparse and will now raise an ImportError if called:
    • create_sparsity_pattern (replaced by pattern_from_mesh)
    • reduce_sparsity_pattern (replaced by Lifter.adapt_sparsity)
    • create_sparsity_pattern_KKT
    • create_sparsity_pattern_master_slave
    • get_bc_indices
  • Compound Sparsity Method Removed: Removed the class method Compound.get_sparsity() to decouple structure layout from sparsity generation.
  • Coloring Functions Hidden: Removed distance2_colors, largest_degree_first_distance2_colors, and smallest_last_distance2_colors from the public tatva.sparse namespace.

New Features & Refactoring

  • Automatic JAX Sparsity Tracing:
    • pattern_from_energy(energy_fn, n_dofs, *static_args): Automatically traces and returns the symmetric CSR sparsity pattern of the Hessian (d²E/du²) for a scalar energy function.
    • pattern_from_virtual_work(virtual_work_fn, n_dofs, trial_arg, test_arg, *static_args): Automatically traces and returns the tangent stiffness matrix sparsity pattern (d²G/dvdu) from a virtual work function.
  • Unified Sparsity Extraction Helpers:
    • pattern_from_mesh(mesh, n_dofs_per_node): Standardized mesh-based sparsity generation.
    • pattern_from_compound(compound_cls, block_wise=False): Extracted compound class sparsity generation to the sparse module.
  • Unified Reduction and Constraint Handling:
    * Added Lifter.adapt_sparsity(sparsity) to automate both the augmentation (adding master-slave coupling) and reduction (retaining only free DOFs) of a sparsity pattern in a single call.

Usage Examples (Tracer with Boundary Conditions)

By passing a Lifter as a static argument, you can trace the sparsity of the reduced system (accounting for boundary conditions) directly:

1. Energy-Based Tracer with BCs

    import jax                                                                                                                                                                                                                                              
    import jax.numpy as jnp                                                                                                                                                                                                                                 
    from tatva.sparse import pattern_from_energy                                                                                                                                                                                                            
                                                                                                                                                                                                                                                            
    @jax.jit                                                                                                                                                                                                                                                
    def total_energy(u):                                                                                                                                                                                                                                    
        # Compute full potential energy                                                                                                                                                                                                                     
        return ...                                                                                                                                                                                                                                          
                                                                                                                                                                                                                                                            
    @jax.jit                                                                                                                                                                                                                                                
    def energy_free(u_free, lf):                                                                                                                                                                                                                            
        # Map free DOFs to full state accounting for BCs                                                                                                                                                                                                    
        u_full = lf.lift_from_zeros(u_free)                                                                                                                                                                                                                 
        return total_energy(u_full)                                                                                                                                                                                                                         
  
    # Trace sparsity of the reduced Hessian directly
    traced_reduced_sparsity = pattern_from_energy(
        energy_free, 
        lifter.size_reduced, 
        lifter  # Passed as static_args
    )

2. Virtual Work-Based Tracer with BCs

   import jax
   import jax.numpy as jnp
   from tatva.sparse import pattern_from_virtual_work
 
   @jax.jit
   def virtual_work(test, trial):
       # Compute virtual work G(test, trial)
       return ...
 
   @jax.jit
   def virtual_work_free(test_free, trial_free, lf):
       # Map free trial and test variables to full states
       test_full = lf.lift_from_zeros(test_free)
       trial_full = lf.lift_from_zeros(trial_free)
       return virtual_work(test_full, trial_full)
 
   # Trace sparsity of the reduced tangent stiffness matrix directly
   traced_reduced_sparsity = pattern_from_virtual_work(
       virtual_work_free,
       lifter.size_reduced,
       "trial_free",
       "test_free",
       lifter  # Passed as static_args
   )

Features

  • changes to the api for creating and reducing sparsity pattern (f2a5d2e)
  • sparse: adds automatic sparsity detection from energy form (4359503)

Bug Fixes

  • add custom_vjp/custom_jvp/remat primitives for tracing (38ab604)
  • add full test suite for checking if all jax primitives are covered (558ead9)
  • add test for sparsity tracer based on fem application (3311f78)
  • add tracer for opaque primitive such as ffi/callback and debug (83b0475)
  • only consider trial-test pair for coupling, vectorize python for-loop inside scan_mp for speed up (3f104d4)