tmdsimpy.jax.NonlinearSolverOMP¶
- class tmdsimpy.jax.NonlinearSolverOMP(config={})¶
Bases:
NonlinearSolverParallel nonlinear solver object that contains several functions.
This solver instance utilizes JAX for shared memory parallelism of linear algebra steps for the linear and nonlinear solves.
- Parameters:
- configdict, optional
Dictionary of settings to be used in the solver. All keys are optional. Keys include:
- max_stepsint, default 20
Maximum number of iterations allowed in the nonlinear solver.
- reform_freqint, default 1
Frequency of recalculating and refactoring Jacobian matrix of the nonlinear problem. 1 corresponds to Newton-Raphson (every step). Larger numbers correspond to BFGS low rank updates in between steps with refactoring. When reform_freq > 1, function being solved must accept the keyword calc_grad=True or calc_grad=False to differentiate if Jacobian matrix should be calculated. If calc_grad=True, then returned tuple should be (R, dRdX). If False, returned tuple should start with (R,), but may return other values past the 0th index of tuple. Function may be a lambda function that completely ignores calc_grad, for instance: fun = lambda X, calc_grad=True : fun0(X)
- verbosebool, default True
Flag for if output should be printed.
- xtoldouble, default None
Convergence tolerance on the L2 norm of the step size (dX) for nsolve. If None, code will set the value to be equal to 1e-6*X0.shape[0] where X0 is the initial guess for a given solution calculation. if xtol is passed to nsolve, that value is used instead
- rtoldouble, default None
Convergence toleranace on the L2 norm of the residual vector (R) for nsolve.
- etoldouble, default None
Convergence tolerance on the energy norm of the inner product of step (dX) and residual (R) or e=np.abs(dX @ R) for nsolve.
- xtol_reldouble, default None
Convergence tolerance on norm(dX) / norm(dX_step0) for nsolve.
- rtol_reldouble, default None
Convergence tolerance on norm(R) / norm(R_step0) for nsolve.
- etol_reldouble, default None
Convergence tolerance on norm(e) / norm(e_step0) for nsolve.
- stopping_tol: list, default [‘xtol’]
List can contain options of ‘xtol’, ‘rtol’, ‘etol’, ‘xtol_rel’, ‘rtol_rel’, ‘etol_rel’. If any of the listed tolerances are satisfied, then iteration is considered converged and exits. Futher development would allow for the list to contain lists of these same options and in a sublist, all options would be required. This has not been implemented.
- accepting_tollist, default []
List that can contain the same set of strings as stopping_tol. Once maximum interactions has been reached, if any of these tolerances are satisified by the final step, then the solution is considered converged. This allows for looser tolerances to be accepted instead of non-convergence, while still using max iterations to try to achieve the tighter tolerances.
- line_search_itersint, default 0
Number of iterations used in line_search. If 0, line search is not used. If line search is desired, a recommended value is less than 10, perhaps about 2 to 5. If it is greater than 0, then function being solved must accept calc_grad=True or calc_grad=False as inputs. The default is 0.
- line_search_tolfloat, default 0.5
If the line search function decreases to be less than the initial value times this tolerance, than it is accepted as converged. This is not intended to be a tight tolerance, line search is just intended to quickly reduce the step in case of poor problem behavior. The default is 0.5.
- line_search_same_signbool, default True
If true, line search tries to only a return a step that does not change the sign of the quantity deltaX @ R(X + alpha*deltaX). The default is True.
See also
tmdsimpy.NonlinearSolverBase class that supports similar operations with less parallelism.
nsolveNonlinear solution method on this class.
Notes
This class inherets some members from tmdsimpy.NonlinearSolver. For instance, eigs could be substituted to try to have better parallelism here.
- __init__(config={})¶
Methods
__init__([config])conditioning_wrapper(fun, CtoP[, RPtoC])Function to create a wrap a provided function and add conditioning.
edit_config(new_config)Edit the solver configuration settings after initialization.
eigs(K[, M, subset_by_index])Conduct eigenvalue analysis for a linear system.
lin_factor(A)Do an LU factorization of a matrix for later linear solutions.
lin_factored_solve(lu_and_piv, b)Solve a linear system that has already been factored.
lin_solve(A, b)Solve the linear system A @ x = b
line_search(fun, X, Rx, deltaX)Line search algorithm to help in the numerical solution to a set of nonlinear equations.
nsolve(fun, X0[, verbose, xtol, Dscale])Numerically solves multiple nonlinear equations to find roots.
- conditioning_wrapper(fun, CtoP, RPtoC=1.0)¶
Function to create a wrap a provided function and add conditioning.
- Parameters:
- funfunction
Function that is to be wrapped in condition space. Function should take two arguments, one is unknown vector Xp, other is optional argument of calc_grad=True. The calc_grad=True is only passed to fun, if calc_grad=False is passed to the fun_conditioned that is returned.
- CtoP(N,) numpy.ndarray
Vector describing conversion from physical coordinates to conditioned coordinates for the unknown vector that is input to fun.
- RPtoCfloat, optional
Scales the full ouptut residual vector by this magnitude. The default is 1.0.
- Returns:
- fun_conditionedfunction
Function that describes the same nonlinear problem as fun, but in a conditioned space. Function takes input of Xc where Xp = CtoP * Xc. Second optional input to the fuction is calc_grad=True. This function returns a residual vector for conditioned inputs. If calc_grad=True, the Jacobian in conditioned space is also returned by this function.
- edit_config(new_config)¶
Edit the solver configuration settings after initialization.
- Parameters:
- new_configdict
Dictionary of key value pairs for the new settings. The settings that can be changed are the same as those when creating a new object.
- Returns:
- None.
See also
NonlinearSolverOMPClass documentation for the setting keys that can be changed.
- eigs(K, M=None, subset_by_index=[0, 2])¶
Conduct eigenvalue analysis for a linear system.
- Parameters:
- K(N,N) numpy.ndarray
Stiffness matrix for general second order system. Assumed to be symmetric.
- M(N,N) numpy.ndarray, optional
Mass matrix for general second order system. This must be symmetric positive definite. The default is None.
- subset_by_indexlist of length 2, optional
Subset indices for which eigenvalues should be calculated. See scipy.linalg.eigh for more details. Let M be the number of requested eigenvalues by this parameter by setting it as [0,M]. The default is [0, 2].
- Returns:
- eigvals(M,) numpy.ndarray
Eigenvalues of the linear problem.
- eigvecs(N,M) numpy.ndarray
Eigenvectors of linear problem with columns corresponding to individual eigenvalues.
See also
scipy.linalg.eighThe eigen problem solver that is called here. This just provides an interface that can be made consistent with different approaches.
- lin_factor(A)¶
Do an LU factorization of a matrix for later linear solutions.
- Parameters:
- A(N,N) numpy.ndarray
Linear system matrix for later solving.
- Returns:
- lu_and_pivtuple
Resulting data from factoring the matrix A, can be passed to lin_factored_solve to solve the linear system.
See also
lin_factored_solveMethod for solving after factoring.
Notes
This method calls jax.scipy.linalg.lu_factor(A).
- lin_factored_solve(lu_and_piv, b)¶
Solve a linear system that has already been factored.
- Parameters:
- lu_and_pivtuple
Results from factoring a matrix with lin_factor(A)
- b(N,) numpy.ndarray
Right hand side vector.
- Returns:
- x(N,) numpy.ndarray
Solution to the linear problem
See also
lin_factorMethod for factoring matrix prior to this solution.
- lin_solve(A, b)¶
Solve the linear system A @ x = b
- Parameters:
- A(N,N) numpy.ndarray
Linear system matrix.
- b(N,) numpy.ndarray
Right hand side vector.
- Returns:
- x(N,) numpy.ndarray
Solution to the linear problem
Notes
Implementation uses jax.numpy.linalg.solve, which supports some parallelism.
- line_search(fun, X, Rx, deltaX)¶
Line search algorithm to help in the numerical solution to a set of nonlinear equations. This is used by nsolve.
- Parameters:
- funfunction
Function to be solved, returns R=fun(X, calc_grad={True or False})[0]. Must accept the input argument calc_grad=True and calc_grad=False. Function may be a lambda function that completely ignores calc_grad.
- X(N,) numpy.ndarray
Values of unknowns at initial point.
- Rx(N,) numpy.ndarray
Residual at X, equal to fun(X)[0].
- deltaX(N,) numpy.ndarray
Step direction of interest, generally calculated based on gradient solution step.
- Returns:
- alphafloat
Fraction of deltaX step that should be taken. Recommended update is X = X + alpha*deltaX
- soldict
Description of final solution state. Has keys of [‘message’, ‘nfev’]. ‘nfev’ is the number of function evaluations completed. ‘message’ describes how line search exited.
See also
NonlinearSolverOMPDocumentation for the solver class describes configurations and settings of the numerical solver that are configured at creation rather than at solution time. Relevant settings are line_search_iters, line_search_tol, line_search_same_sign.
nsolveNonlinear solver routine that calls this function (Newton-Raphson + BFGS Solver)
Notes
The line search algorithm here is based on [1]. In the finite element context, the objective is to find the zero of an ‘energy’ norm of R^T deltaX. The bisection algorithm is used to find a solution for R(X + alpha*deltaX) with alpha in [0, 1]. A very loose tolerance is generally desired to minimize additional computational cost of this function before returing to nsolve.
References
[1]Matthies, H., G. Strang, 1979. The solution of nonlinear finite element equations. International Journal for Numerical Methods in Engineering 14, 1613–1626. https://doi.org/10.1002/nme.1620141104
- nsolve(fun, X0, verbose=None, xtol=None, Dscale=1.0)¶
Numerically solves multiple nonlinear equations to find roots.
Solver settings are set at initialization of NonlinearSolverOMP (see that documentation).
- Parameters:
- funfunction handle
Function to be solved, function returns two arguments of R (residual, (N,) numpy.ndarray) and dRdX (residual jacobian, (N,N) numpy.ndarray). If config[‘reform_freq’] > 1, then fun should take two arguments The first is X, the second is a bool calc_grad where if True, fun returns a tuple of (R,dRdX). If False, fun just returns a tuple (R,) Function may return additional values in either tuple, but the additional values will be ignored here.
- X0(N,) numpy.ndarray
Initial guess of the solution to the nonlinear problem.
- verbosebool or None, optional
Flag to print convergence information if True. If None, then the configuration setting for ‘verbose’ from initialization will be used (default True) The default is None.
- xtolfloat, optional
Tolerance to check for convergence on the step size. If None, then self.config[‘xtol’] is used. If that is also None, then 1e-6*X0.shape[0] is used as the x tolerance. Passing in a value here does not change the config value permanently (not parallel safe though). The default is None.
- Returns:
- X(N,) numpy.ndarray
Solution to the nonlinear problem that satisfies tolerances or from last step.
- R(N,) numpy.ndarray
Residual vector from the last function evaluation (does not in generally correspond to value at X to save extra evaluation of fun).
- dRdX(N,N) numpy.ndarray
Last residual Jacobian as evaluated during solution, not at final X.
- soldict
Description of final convergence state. Has keys of [‘message’, ‘nfev’, ‘njev’, ‘success’]. ‘success’ is a bool with True corresponding to convergence. ‘nfev’ is the number of function evaluations completed. ‘njev’ is the number of jacobian evaluations. ‘message’ is either ‘Converged’ or ‘failed’. Use the bool from ‘success’ rather than the message for decisions. ‘nfev’ does not include any function evaluations done as part of the line search routine.
- Other Parameters:
- Dscalefloat or numpy.ndarray, optional
This argument does nothing. Conditioning of the numerical problem should be achieved by wrapping the problem of interest rather than here.
See also
NonlinearSolverOMPDocumentation for the solver class describes configurations and settings of the numerical solver that are configured at creation rather than at solution time.
line_searchClass method that may be used to improve convergence of nsolve if the appropriate solver settings are used.
Notes
This function uses either a full Newton-Raphson (NR) solver approach or Broyden-Fletcher-Goldfarb-Shanno (BFGS), which uses fewer NR iterations with some approximations of Jacobian between NR iterations. For BFGS see Algorithm 7.4 in [1].
The output status of current errors / norms of residual etc. are intended to provide easy checks to see what is going on during solutions. These outputs are slightly convoluted in that some outputs are for the previous iteration, check code for exact details.
References
[1]Nocedal, J., S.J. Wright, 2006. Numerical optimization, 2nd ed, Springer series in operations research. Springer, New York.