- lm_variableName of the variable(s) that is to be condensed out. Usually this will be the Lagrange multiplier variable(s).
C++ Type:std::vector<std::string>
Controllable:No
Description:Name of the variable(s) that is to be condensed out. Usually this will be the Lagrange multiplier variable(s).
- preconditionerPreconditioner type.
C++ Type:std::vector<std::string>
Controllable:No
Description:Preconditioner type.
- primary_variableName of the variable(s) that couples with the variable(s) specified in the `variable` block. Usually this is the primary variable that the Lagrange multiplier correspond to.
C++ Type:std::vector<std::string>
Controllable:No
Description:Name of the variable(s) that couples with the variable(s) specified in the `variable` block. Usually this is the primary variable that the Lagrange multiplier correspond to.
VCP
Varialble condensation preconditioner (VCP) condenses out specified variable(s) from the Jacobian matrix and produces a system of equations with less unkowns to be solved by the underlying preconditioners.
Overview
The Variable Condensation Preconditioner (VCP) is designed to condense out variables from the linear system of equations and apply the preconditioner/solver on the reduced simplified system of equations. The development of VCP is motivated by the need to enable a broader range of robust and scalable preconditioners for problems that have a saddle point type of Jacobian. The saddle point type of Jacobian may come from different applications. One typical example is the enforcement of constraints using Lagrange multipliers. Its special numerical character prevents the usage of many scalable iterative solvers. To resolve this issue, a static condensation step is carried out in VCP to remove the Degree of Freedoms (DoFs) that are associated with the Lagrange multipliers. This may result in an easy-to-solve system (sometimes it is positive definite ) which can be handled by a broader range of solvers/preconditioners with improved efficiency. With VCP, we can efficiently apply iterative solvers, e.g., BoomerAMG, to mortar-based mechanical contact problems.
System Simplification
To illustrate the saddle point structure of the Jacobian matrix and how it can be simplified by static condensation of the Lagrange multiplier, we take the Jacobian matrix from a simple diffusion problem with equal value constraint as an example. The system of equations at a typical time step can be written as a block matrix as follows, (1) Here, we omit the identifier of time for simplicity. The first subscript and denote the primary and secondary subdomains, respectively. The second subscript denotes the part of the subdomain that is in contact and denotes the rest of the subdomain. The blocks denote the respective stiffness matrices. The block represents the coupling between the Lagrange multipliers and the primal variable in the secondary subdomain. The block denotes the coupling between the Lagrange multipliers and the primal variable in the primary subdomain.
The system of equations from mortar-based mechanical contact has a similar saddle point character, but is more complex than Eq. (1), considering the primary and secondary surfaces being partially in contact. For readers who are interested in the Jacobian matrix from mortar-based mechanical contact, please refer to (Popp et al., 2010).
Condensation of the Lagrange Multiplier
The discrete Lagrange multipliers (i.e., ) can be eliminated by condensation as follows, (2)
By substituting Eq. (2) into Eq. (1), we obtain a simplified linear system of equations that contains only the primal variable DOFs,
(3) This condensed system (i.e., Eq. (3)) is positive definite and therefore state-of-art iterative solution techniques, such as multigrid methods, are applicable. As a post-processing step, the Lagrange multipliers can be recovered from the displacement following Eq. (2).
Dual Basis Function
The computation of in Eq. (2) and Eq. (3) can be reduced by using dual basis for the Lagrange multipliers. The dual basis is a relative definition to the standard basis, which satisfies a biorthogonal condition as follows (4) where is the standard shape function, is the dual shape function, and is the Kronecker delta function. This biorthogonal condition can be assumed to hold in every lower-dimensional element . Owing to the biorthogonality property of the dual basis functions, the integral matrix become strict diagonal. Thus computation of and condensation steps in Eq. (2) and Eq. (3) become trivial.
In order to reduce the computational cost brought by the condensation steps (see Eq. (2) and Eq. (3)), we recommend the usage of dual basis function for the Lagrange multipliers. Meanwhile, we suggest setting the option is_lm_coupling_diagonal = true
in the preconditioning block to let VCP take the diagonal structure of the couple matrix () into account for improved efficiency. If D is not diagonal, but the number of multiplier DoFs is small, VCP will be still beneficial. It may be expensive to compute non-diagonal D when the number of multiplier DOFs is large.
One can enable the usage of dual basis by enabling use_dual = true
in the Variables
block:
[Variables]
[./lm]
order = FIRST
family = LAGRANGE
use_dual = true
[../]
[]
Or, for mortar-based contact problems, the dual basis function is used by default for the Lagrange multipliers (while using the contact action). An example input block for contact action is as follows:
[Contact]
[frictionless]
primary = plank_right
secondary = block_left
formulation = mortar
c_normal = 1e0
[]
[]
(../moose/modules/contact/test/tests/mortar_tm/2d/frictionless_first/small.i)VCP Workflow
A schematic is included in Figure 1 to demonstrate the solution process of VCP. Compared to the standard precondition and solve procedure, VCP features two additional customized computation steps (i.e., one to condense out the variable and the other to obtain the full solution vector) (see Figure 1). During static condensation of the variable (e.g., ), the DoFs are obtained for both the variable itself () and its coupled variable (). Based on this information, the coupling matrices (i.e., and ) will be extracted from the original Jacobian matrix. Then a reduced system of equations will be obtained with the necessary submatrix operations following Eq. (3). After solving the reduced system of equations, we obtain the primal variable solution vector, which is then utilized to update the variable (see Eq. (2)) and assemble the full solution vector.
Special Designs in VCP
Several special designs in VCP foster improved performance:
Adaptive variable condensation The idea is to obtain the actual DoFs that have zero diagonal entries by checking the Jacobian matrix at runtime. This refines the DoF list such that variable condensation will only be carried out for those DoFs that actually result in a saddle point structure. For contact problems, this will make sure that variable condensation will only happen when the material bodies come into contact. One can optionally turn on/off this capability by setting the
adaptive_condensation = true
orfalse
.Standard basis As mentioned above, we recommend the usage of dual basis to reduce computational overhead due to the condensation step. However, it can happen if the dual basis does not work for certain problems. In this case, the user can set
use_dual = false
to use the standard basis functions. Then has off-diagonal entries. During the computation of , the user can choose to either use an LU solver (by settingis_lm_coupling_diagonal = false
) or obtain an approximated inverse using the diagonal entries (by settingis_lm_coupling_diagonal = true
).Generalized condensation Although we are focused on using VCP for mortar-based contact problems with a saddle point structure, VCP is developed to be applicable to general problems in which improved conditioning is achievable via a reduced number of DoFs.
VCP acts on the discretized system of equations and is designed to be as general as possible. However, the current implementation is mainly tested for mortar-based mechanical contact problems. We are actively improving this implementation and are looking for applications beyond contact. Therefore, please feel free to create an issue or start a discussion if you may come across any problem with VCP.
Performance
As an illustration, we solve the 2D Hertzian problem by using VCP with several sub-preconditioner types, including BoomerAMG (AMG), successive over-relaxation (SOR), additive Schwarz method (ASM), and block Jacobi (BJAC). For all the cases, we set adaptive_condensation = true
and is_lm_coupling_diagonal = true
. Note that here, ASM, and BJAC converge for the mortar-based mechanical contact problem, both as a standalone preconditioner and as a sub-preconditioner. AMG and SOR stagnate as a standalone preconditioner, while converge well as a sub-preconditioner under VCP. Figure 2 shows the performance of VCP in terms of total wall time and total number of linear iterations. It can be seen that VCP can pretty efficiently converge using AMG and SOR, whereas the standard preconditioner stagnates or diverges. For the other sub-preconditioner types, VCP is still more efficient than the standard preconditioner, despite the additional computational cost from the variable condensation step. This is because a better-conditioned system is obtained after static condensation of the Lagrange multipliers. For readers who are interested in getting more details, please refer to (Yushu et al., 2021). Note the performance of VCP for problems with increased complexities, e.g., larger, multi-physics problems, is to be examined in the future.
Example Input File Syntax
[Preconditioning]
[vcp]
type = VCP
full = true
lm_variable = 'leftright_normal_lm'
primary_variable = 'disp_x'
preconditioner = 'AMG'
is_lm_coupling_diagonal = true
adaptive_condensation = true
[]
[]
(../moose/modules/contact/test/tests/dual_mortar/dm_mechanical_contact_precon.i)Input Parameters
- adaptive_condensationTrueBy default VCP will check the Jacobian and only condense the rows with zero diagonals. Set to false if you want to condense out all the specified variable dofs.
Default:True
C++ Type:bool
Controllable:No
Description:By default VCP will check the Jacobian and only condense the rows with zero diagonals. Set to false if you want to condense out all the specified variable dofs.
- coupled_groupsList multiple space separated groups of comma separated variables. Off-diagonal jacobians will be generated for all pairs within a group.
C++ Type:std::vector<NonlinearVariableName>
Controllable:No
Description:List multiple space separated groups of comma separated variables. Off-diagonal jacobians will be generated for all pairs within a group.
- fullFalseSet to true if you want the full set of couplings between variables simply for convenience so you don't have to set every off_diag_row and off_diag_column combination.
Default:False
C++ Type:bool
Controllable:No
Description:Set to true if you want the full set of couplings between variables simply for convenience so you don't have to set every off_diag_row and off_diag_column combination.
- is_lm_coupling_diagonalFalseSet to true if you are sure the coupling matrix between Lagrange multiplier variable and the coupled primal variable is strict diagonal. This will speedup the linear solve. Otherwise set to false to ensure linear solve accuracy.
Default:False
C++ Type:bool
Controllable:No
Description:Set to true if you are sure the coupling matrix between Lagrange multiplier variable and the coupled primal variable is strict diagonal. This will speedup the linear solve. Otherwise set to false to ensure linear solve accuracy.
- ksp_normunpreconditionedSets the norm that is used for convergence testing
Default:unpreconditioned
C++ Type:MooseEnum
Controllable:No
Description:Sets the norm that is used for convergence testing
- off_diag_columnThe variable names for the off-diagonal columns you want to add into the matrix; they will be associated with an off-diagonal row from the same position in off_diag_row.
C++ Type:std::vector<NonlinearVariableName>
Controllable:No
Description:The variable names for the off-diagonal columns you want to add into the matrix; they will be associated with an off-diagonal row from the same position in off_diag_row.
- off_diag_rowThe variable names for the off-diagonal rows you want to add into the matrix; they will be associated with an off-diagonal column from the same position in off_diag_column.
C++ Type:std::vector<NonlinearVariableName>
Controllable:No
Description:The variable names for the off-diagonal rows you want to add into the matrix; they will be associated with an off-diagonal column from the same position in off_diag_column.
- pc_sidedefaultPreconditioning side
Default:default
C++ Type:MooseEnum
Controllable:No
Description:Preconditioning side
Optional Parameters
- control_tagsAdds user-defined labels for accessing object parameters via control logic.
C++ Type:std::vector<std::string>
Controllable:No
Description:Adds user-defined labels for accessing object parameters via control logic.
- enableTrueSet the enabled status of the MooseObject.
Default:True
C++ Type:bool
Controllable:No
Description:Set the enabled status of the MooseObject.
Advanced Parameters
- mffd_typewpSpecifies the finite differencing type for Jacobian-free solve types. Note that the default is wp (for Walker and Pernice).
Default:wp
C++ Type:MooseEnum
Controllable:No
Description:Specifies the finite differencing type for Jacobian-free solve types. Note that the default is wp (for Walker and Pernice).
- petsc_optionsSingleton PETSc options
C++ Type:MultiMooseEnum
Controllable:No
Description:Singleton PETSc options
- petsc_options_inameNames of PETSc name/value pairs
C++ Type:MultiMooseEnum
Controllable:No
Description:Names of PETSc name/value pairs
- petsc_options_valueValues of PETSc name/value pairs (must correspond with "petsc_options_iname"
C++ Type:std::vector<std::string>
Controllable:No
Description:Values of PETSc name/value pairs (must correspond with "petsc_options_iname"
- solve_typePJFNK: Preconditioned Jacobian-Free Newton Krylov JFNK: Jacobian-Free Newton Krylov NEWTON: Full Newton Solve FD: Use finite differences to compute Jacobian LINEAR: Solving a linear problem
C++ Type:MooseEnum
Controllable:No
Description:PJFNK: Preconditioned Jacobian-Free Newton Krylov JFNK: Jacobian-Free Newton Krylov NEWTON: Full Newton Solve FD: Use finite differences to compute Jacobian LINEAR: Solving a linear problem
Petsc Parameters
References
- Alexander Popp, Markus Gitterle, Michael W Gee, and Wolfgang A Wall.
A dual mortar approach for 3D finite deformation contact with consistent linearization.
International Journal for Numerical Methods in Engineering, 83(11):1428–1465, 2010.[BibTeX]
- Dewen Yushu, Antonio Martin Recuero, Daniel Schwen, Alexander Lindsay, and Benjamin Spencer.
M3 milestone: advanced contact 2021.
2021.[BibTeX]