Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #include "FiniteDifferencePreconditioner.h" 11 : 12 : // MOOSE includes 13 : #include "FEProblem.h" 14 : #include "MooseVariableFE.h" 15 : #include "NonlinearSystem.h" 16 : 17 : #include "libmesh/coupling_matrix.h" 18 : 19 : registerMooseObjectAliased("MooseApp", FiniteDifferencePreconditioner, "FDP"); 20 : 21 : InputParameters 22 14495 : FiniteDifferencePreconditioner::validParams() 23 : { 24 14495 : InputParameters params = MoosePreconditioner::validParams(); 25 : 26 14495 : params.addClassDescription("Finite difference preconditioner (FDP) builds a numerical Jacobian " 27 : "for preconditioning, only use for testing and verification."); 28 : 29 43485 : params.addParam<bool>("implicit_geometric_coupling", 30 28990 : false, 31 : "Set to true if you want to add entries into the " 32 : "matrix for degrees of freedom that might be coupled " 33 : "by inspection of the geometric search objects."); 34 : 35 14495 : MooseEnum finite_difference_type("standard coloring", "coloring"); 36 14495 : params.addParam<MooseEnum>("finite_difference_type", 37 : finite_difference_type, 38 : "standard: standard finite difference" 39 : "coloring: finite difference based on coloring"); 40 : 41 28990 : return params; 42 14495 : } 43 : 44 115 : FiniteDifferencePreconditioner::FiniteDifferencePreconditioner(const InputParameters & params) 45 : : MoosePreconditioner(params), 46 115 : _finite_difference_type(getParam<MooseEnum>("finite_difference_type")) 47 : { 48 115 : if (n_processors() > 1) 49 46 : mooseWarning("Finite differencing to assemble the Jacobian is MUCH MUCH slower than forming " 50 : "the Jacobian by hand, so don't complain about performance if you use it!"); 51 : 52 115 : NonlinearSystemBase & nl = _fe_problem.getNonlinearSystemBase(_nl_sys_num); 53 115 : unsigned int n_vars = nl.nVariables(); 54 : 55 115 : std::unique_ptr<CouplingMatrix> cm = std::make_unique<CouplingMatrix>(n_vars); 56 : 57 115 : bool full = getParam<bool>("full"); 58 : 59 : // standard finite difference method will add off-diagonal entries 60 115 : if (_finite_difference_type == "standard") 61 22 : full = true; 62 : 63 115 : if (!full) 64 : { 65 : // put 1s on diagonal 66 129 : for (unsigned int i = 0; i < n_vars; i++) 67 74 : (*cm)(i, i) = 1; 68 : 69 : // off-diagonal entries 70 55 : std::vector<std::vector<unsigned int>> off_diag(n_vars); 71 55 : if (isParamValid("off_diag_row") && isParamValid("off_diag_column")) 72 : 73 14 : for (const auto i : index_range(getParam<std::vector<NonlinearVariableName>>("off_diag_row"))) 74 : { 75 : unsigned int row = 76 14 : nl.getVariable(0, getParam<std::vector<NonlinearVariableName>>("off_diag_row")[i]) 77 7 : .number(); 78 : unsigned int column = 79 14 : nl.getVariable(0, getParam<std::vector<NonlinearVariableName>>("off_diag_column")[i]) 80 7 : .number(); 81 7 : (*cm)(row, column) = 1; 82 : } 83 : 84 : // TODO: handle coupling entries between NL-vars and SCALAR-vars 85 55 : } 86 : else 87 : { 88 160 : for (unsigned int i = 0; i < n_vars; i++) 89 280 : for (unsigned int j = 0; j < n_vars; j++) 90 180 : (*cm)(i, j) = 1; 91 : } 92 : 93 115 : setCouplingMatrix(std::move(cm)); 94 : 95 115 : bool implicit_geometric_coupling = getParam<bool>("implicit_geometric_coupling"); 96 : 97 115 : nl.addImplicitGeometricCouplingEntriesToJacobian(implicit_geometric_coupling); 98 : 99 : // Set the jacobian to null so that libMesh won't override our finite differenced jacobian 100 115 : nl.useFiniteDifferencedPreconditioner(true); 101 115 : }