fol.solvers#
Solve strategies provided by FoLax.
Finite element linear solver class#
Authors: Reza Najian Asl, RezaNajian Date: May, 2024 License: FOL/LICENSE
- class fol.solvers.fe_solver.FiniteElementSolver(fe_solver_name, fe_loss_function, fe_solver_settings={})[source]#
Bases:
SolverBase solver for finite element systems driven by a
FiniteElementLoss.This class provides a common interface for solvers that operate on FE loss functions and require assembling and solving linear systems of the form:
K(u, p) * delta = -R(u, p)
where
Kis a sparse tangent (Jacobian) matrix andRis a residual vector produced by afol.loss_functions.fe_loss.FiniteElementLoss.ComputeJacobianMatrixAndResidualVectorinstance.The class mainly manages linear-solver selection and configuration. It does not define a problem-specific
Solveroutine; derived solver classes implement their ownSolvemethod (e.g., linear residual-based solvers, nonlinear Newton solvers, adjoint solvers) and callLinearSolveto solve the assembled linear system.- Parameters:
fe_solver_name (str) – Name identifier for the solver instance.
fe_loss_function (FiniteElementLoss) – Finite element loss object that provides problem-specific residuals and tangent matrices.
fe_solver_settings (dict, optional) – Solver configuration dictionary. If it contains the key
"linear_solver_settings", the settings are merged with defaults.
- fe_loss_function#
Loss object used to assemble residuals and tangent matrices.
- Type:
- fe_solver_settings#
User-provided solver settings dictionary.
- Type:
dict
- linear_solver_settings#
Linear solver configuration with default keys:
"solver","tol","atol","maxiter", and"pre-conditioner".- Type:
dict
- LinearSolve#
Function handle assigned in
Initialize()to the selected linear solve routine.- Type:
callable
Notes
Supported linear solver backends are selected via
linear_solver_settings["solver"]. The available options are:"JAX-bicgstab","JAX-direct", and PETSc-based Krylov methods"PETSc-bcgsl","PETSc-tfqmr","PETSc-minres","PETSc-gmres". If PETSc is requested but unavailable, the solver falls back to"JAX-bicgstab".- Initialize()[source]#
Initialize and select the linear solver backend.
This method merges user-provided
linear_solver_settings(if present) with defaults and assigns theLinearSolvecallable to one of the available backends.- Returns:
None
- Raises:
ValueError – If an unknown solver name is provided in
linear_solver_settings["solver"].
- JaxBicgstabLinearSolver(tangent_matrix, residual_vector, dofs_vector)[source]#
Solve the linear system using JAX BiCGSTAB.
The solver computes a DOF increment by solving:
tangent_matrix * delta_dofs = -residual_vector
using the iterative BiCGSTAB method from
jax.scipy.sparse.linalg. The optional initial guess is taken asdofs_vector.- Parameters:
tangent_matrix (jax.experimental.sparse.BCOO) – Global tangent (Jacobian) matrix in BCOO sparse format.
residual_vector (jax.numpy.ndarray) – Global residual vector.
dofs_vector (jax.numpy.ndarray) – Initial guess for the iterative solver.
- Returns:
Increment vector
delta_dofssolving the linear system.- Return type:
jax.numpy.ndarray
- JaxDirectLinearSolver(tangent_matrix, residual_vector, dofs_vector)[source]#
Solve the linear system using a direct sparse solve.
The input BCOO matrix is converted to a SciPy CSR sparse matrix and solved using
jax.experimental.sparse.linalg.spsolvewith the right hand side-residual_vector.- Parameters:
tangent_matrix (jax.experimental.sparse.BCOO) – Global tangent (Jacobian) matrix in BCOO sparse format.
residual_vector (jax.numpy.ndarray) – Global residual vector.
dofs_vector (jax.numpy.ndarray) – Unused by the direct solver (kept for a consistent interface).
- Returns:
Increment vector
delta_dofssolving the linear system.- Return type:
jax.numpy.ndarray
- PETScLinearSolver(tangent_matrix, residual_vector, dofs_vector)[source]#
Solve the linear system using PETSc KSP.
The input BCOO matrix is converted to a SciPy CSR matrix and then wrapped into a PETSc AIJ matrix. The right hand side is set to
-residual_vector. The KSP type is selected from the solver name provided inInitialize()(e.g.,gmres,minres,tfqmr). The PETSc preconditioner type is set vialinear_solver_settings["pre-conditioner"].- Parameters:
tangent_matrix (jax.experimental.sparse.BCOO) – Global tangent (Jacobian) matrix in BCOO sparse format.
residual_vector (jax.numpy.ndarray) – Global residual vector.
dofs_vector (jax.numpy.ndarray) – Unused by PETSc (kept for a consistent interface).
- Returns:
Increment vector
delta_dofsreturned by PETSc.- Return type:
numpy.ndarray
- Raises:
RuntimeError – If PETSc is not available in the current environment.
Adjoint-based Finite Element solver#
Authors: Reza Najian Asl, RezaNajian Date: January, 2025 License: FOL/LICENSE
- class fol.solvers.adjoint_fe_solver.AdjointFiniteElementSolver(adj_fe_solver_name, fe_response, adj_fe_solver_settings={})[source]#
Bases:
FiniteElementSolverAdjoint finite element solver for gradient and sensitivity analysis.
This class solves the adjoint system associated with a forward finite element problem. The adjoint formulation is typically used in PDE-constrained optimization, inverse problems, and sensitivity analysis to efficiently compute gradients of a scalar objective (loss) function with respect to control variables.
The adjoint system is constructed using a
FiniteElementResponseobject, which provides the loss functional, the adjoint Jacobian matrix, and the adjoint right-hand side vector.The class inherits from
FiniteElementSolverand reuses its linear system solution infrastructure.Mathematical Formulation#
Let the forward problem be defined as:
R(u, m) = 0
- where:
u : state (degrees of freedom), m : control variables.
Let the scalar objective (loss) be:
J(u, m)
The adjoint variable λ satisfies the adjoint equation:
(∂R/∂u)ᵀ λ = - ∂J/∂u
- where:
∂R/∂u : Jacobian of the residual with respect to the state, ∂J/∂u : gradient of the loss with respect to the state.
Boundary conditions are assumed to be applied directly to the adjoint Jacobian and right-hand side prior to solving the system.
- param adj_fe_solver_name:
Name of the adjoint finite element solver instance.
- type adj_fe_solver_name:
str
- param fe_response:
Object responsible for defining the loss functional and assembling the adjoint Jacobian matrix and right-hand side vector.
- type fe_response:
FiniteElementResponse
- param adj_fe_solver_settings:
Dictionary containing solver-specific settings such as linear solver type, tolerances, or preconditioning options. Default is an empty dictionary.
- type adj_fe_solver_settings:
dict, optional
- fe_response#
Reference to the finite element response object used to assemble adjoint quantities.
- Type:
- Solve(current_control_vars, current_dofs, current_adjoint_dofs)[source]#
Assemble and solve the adjoint linear system.
This method constructs the adjoint Jacobian matrix and right-hand side vector based on the current control variables and forward solution. The resulting linear system is then solved for the adjoint degrees of freedom.
The right-hand side vector is multiplied by
-1to ensure consistency with the solver sign convention used inLinearSolve().- Parameters:
current_control_vars (jnp.array) – Current values of the control variables.
current_dofs (jnp.array) – Current forward solution degrees of freedom.
current_adjoint_dofs (jnp.array) – Initial guess or previous values of the adjoint degrees of freedom.
- Returns:
The updated adjoint degrees of freedom obtained by solving the adjoint linear system.
- Return type:
jnp.array
Linear residual-based Finite Element solver#
Authors: Reza Najian Asl, RezaNajian Date: May, 2024 License: FOL/LICENSE
- class fol.solvers.fe_linear_residual_based_solver.FiniteElementLinearResidualBasedSolver(fe_solver_name, fe_loss_function, fe_solver_settings={})[source]#
Bases:
FiniteElementSolverLinear residual-based finite element solver.
This solver advances the solution of a (typically) linear finite element system using a residual-based update. Given the current state (DOFs) and control variables, it:
Applies Dirichlet boundary conditions to the current DOF vector.
Assembles the Jacobian matrix and residual vector of the FE loss/residual.
Solves a linear system to obtain an increment (update) in DOFs.
Returns the updated DOF vector.
The assembly and boundary-condition operations are delegated to the underlying loss function (
self.fe_loss_function), while the linear solve is handled byFiniteElementSolver.LinearSolve().Linear Residual Solver Formulation#
Let
ube the vector of degrees of freedom (state) andmthe control variables. After enforcing Dirichlet boundary conditions onu, the loss function provides:J: the Jacobian matrix (e.g., tangent stiffness matrix)r: the residual vector
The solver computes an increment
Δufrom a linear system of the form:J(u, m) Δu = r(u, m)
and updates the state as:
u_new = u_cu + Δu
where
u_cuis the given/current DOF vector after applying Dirichlet boundary conditions.Notes
This class is intended for linear (or linearized) problems where a single residual-based correction is sufficient per solve call.
Sign conventions for the residual (whether the system is
J Δu = rorJ Δu = -r) are assumed to be consistent with the implementation ofFiniteElementSolver.LinearSolve()and the loss function assembly.
- Solve(current_control_vars, current_dofs)[source]#
Assemble and solve a linear residual-based update for the DOFs.
This method applies Dirichlet boundary conditions to the current DOFs, then uses the FE loss function to compute the Jacobian matrix and residual vector. It solves the resulting linear system to obtain the DOF increment and returns the updated DOF vector.
- Parameters:
current_control_vars (jnp.array) – Current values of the control variables (design/parameters) used to assemble the system.
current_dofs (jnp.array) – Current degrees of freedom (state vector) serving as the starting point for the update.
- Returns:
Updated degrees of freedom after applying Dirichlet boundary conditions and adding the computed increment.
- Return type:
jnp.array
Nonlinear finite element solver with incremental Newton–Raphson iterations and Gauss-point state variable updates#
Authors: Reza Najian Asl, RezaNajian Date: July, 2024 License: FOL/LICENSE
- class fol.solvers.fe_nonlinear_residual_based_solver_with_history_update.FiniteElementNonLinearResidualBasedSolverWithStateUpdate(fe_solver_name, fe_loss_function, fe_solver_settings={}, history_plot_settings={})[source]#
Bases:
FiniteElementNonLinearResidualBasedSolverNonlinear residual-based finite element solver with Gauss-point state updates.
This solver extends
FiniteElementNonLinearResidualBasedSolverby coupling global Newton–Raphson iterations for the degrees of freedom with local updates of Gauss-point (integration-point) state variables such as internal or history-dependent quantities.The solution procedure is performed using incremental load steps defined by
nonlinear_solver_settings["load_incr"]. For each load step, the solver applies boundary conditions, performs Newton iterations, updates local state variables, and records convergence information.This class is intended for nonlinear, history-dependent problems such as elastoplasticity, damage, or viscoelasticity, where consistent updates of integration-point state variables are required.
- Solve(current_control_vars, current_dofs, current_state=None, return_all_steps=False)[source]#
Solve the nonlinear finite element system using incremental loading.
The solver advances the solution through a sequence of load steps. Within each load step, Newton–Raphson iterations are performed to enforce global equilibrium. At every Newton iteration, the Jacobian matrix, residual vector, and updated Gauss-point state variables are assembled by the loss function.
Convergence is declared when at least one of the following conditions is satisfied: the residual norm falls below the absolute tolerance, the update norm falls below the relative tolerance, or the maximum number of Newton iterations is reached.
- Parameters:
current_control_vars (jax.numpy.ndarray) – Control variables used to assemble the system (e.g., material parameters).
current_dofs (jax.numpy.ndarray) – Initial degrees of freedom representing the current global state.
current_state (jax.numpy.ndarray, optional) – Initial Gauss-point state variables. If not provided, a zero state field is initialized based on the element type and integration scheme.
return_all_steps (bool, optional) – If
False(default), only the final load step solution and state are returned. IfTrue, the solution and state for all load steps are returned.
- Returns:
The updated degrees of freedom, the corresponding Gauss-point state variables, and a dictionary containing convergence history for each load step.
- Return type:
Tuple[jax.numpy.ndarray, jax.numpy.ndarray, dict]
- Raises:
ValueError – If the residual norm becomes NaN during the Newton iterations, indicating a breakdown of the nonlinear solve.
Nonlinear finite element solver with incremental Newton–Raphson iterations#
Authors: Reza Najian Asl, RezaNajian Date: July, 2024 License: FOL/LICENSE
- class fol.solvers.fe_nonlinear_residual_based_solver.FiniteElementNonLinearResidualBasedSolver(fe_solver_name, fe_loss_function, fe_solver_settings={}, history_plot_settings={})[source]#
Bases:
FiniteElementLinearResidualBasedSolverNonlinear residual-based finite element solver using incremental Newton–Raphson.
This solver extends
FiniteElementLinearResidualBasedSolverto support nonlinear problems by repeatedly assembling the tangent (Jacobian) matrix and residual vector and applying Newton–Raphson updates to the global degrees of freedom (DOFs).Loading is applied incrementally according to
self.nonlinear_solver_settings["load_incr"]. For each load step, the solver iterates until convergence is detected or the maximum number of Newton iterations is reached. Convergence history (residual norms and update norms) is stored per load step and can optionally be plotted viaPlotHistoryDict().Typical applications include problems with geometric nonlinearities, nonlinear material behavior (e.g., hyperelasticity, plasticity, damage), or nonlinear boundary-condition effects.
- Initialize()[source]#
Initialize the solver and merge nonlinear and plotting settings.
This method calls the base class initialization and updates the nonlinear solver settings from
fe_solver_settings["nonlinear_solver_settings"]if provided. It also merges the user-specified history plotting settings with the default plotting configuration.
- Solve(current_control_vars, current_dofs_np)[source]#
Solve the nonlinear FE system using incremental Newton–Raphson iterations.
The load is applied over
load_incrsteps. For each load step, Dirichlet boundary conditions are applied at the current load factor, the Jacobian and residual are assembled via the loss function, and a Newton update is computed usingLinearSolve(). The DOFs are updated until convergence is detected or the iteration limit is reached. Convergence metrics are recorded per load step and can be plotted viaPlotHistoryDict().Convergence is considered achieved when at least one of the following conditions is satisfied: - Residual norm <
abs_tol- Update norm <rel_tol- Iteration count reachesmaxiter- Parameters:
current_control_vars (jax.numpy.ndarray) – Control variables passed to the loss function (e.g., material or design parameters).
current_dofs_np (jax.numpy.ndarray) – Initial DOF vector. Converted to a JAX array internally.
- Returns:
Converged DOF vector at the end of the final load step.
- Return type:
jax.numpy.ndarray
- Raises:
ValueError – If the residual norm becomes NaN during Newton iterations.