17 #include "libmesh/petsc_nonlinear_solver.h" 18 #include "libmesh/petsc_solver_exception.h" 19 #include "libmesh/petsc_vector.h" 31 :
LineSearch(parameters), _nl(_fe_problem.getNonlinearSystemBase(0))
33 _solver =
dynamic_cast<PetscNonlinearSolver<Real> *
>(
37 "This line search operates only with Petsc, so Petsc must be your nonlinear solver.");
45 mooseError(
"This line search only makes sense in a displaced context");
51 PetscBool changed_y = PETSC_FALSE;
53 SNESLineSearch line_search;
54 PetscReal fnorm, xnorm, ynorm;
57 LibmeshPetscCall(SNESGetLineSearch(snes, &line_search));
58 LibmeshPetscCall(SNESLineSearchGetVecs(line_search, &
X, &
F, &
Y, &W, &
G));
59 LibmeshPetscCall(SNESLineSearchGetNorms(line_search, &xnorm, &fnorm, &ynorm));
60 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_SUCCEEDED));
62 LibmeshPetscCall(SNESLineSearchPreCheck(line_search,
X,
Y, &changed_y));
65 LibmeshPetscCall(VecWAXPY(W, -1.,
Y,
X));
68 PetscVector<Number> solution(W, this->
comm());
85 std::set<dof_id_type> nodes_displaced;
87 std::vector<unsigned int> disp_nums;
93 for (
const auto & pen_loc : pen_locs)
94 for (
const auto & pinfo_pair : pen_loc.second->_penetration_info)
96 auto node_id = pinfo_pair.first;
97 auto pen_info = pinfo_pair.second;
100 if (pen_info && pen_info->_distance > 0)
105 auto pair = nodes_displaced.insert(node_id);
106 mooseAssert(pair.second,
"Node id " << node_id <<
" has already been displaced");
109 const auto & node =
mesh.node_ref(node_id);
116 auto required_solution_change = pen_info->_distance * pen_info->_normal;
119 std::vector<PetscInt> indices;
120 std::vector<PetscScalar> values;
121 for (
auto disp_num : disp_nums)
123 auto dof_number = node.dof_number(0, disp_num, 0);
124 indices.push_back(static_cast<PetscInt>(dof_number));
125 values.push_back(static_cast<PetscScalar>(required_solution_change(
component++)));
127 LibmeshPetscCall(VecSetValues(
128 W, static_cast<PetscInt>(indices.size()), indices.data(), values.data(), ADD_VALUES));
132 LibmeshPetscCall(VecAssemblyBegin(W));
133 LibmeshPetscCall(VecAssemblyEnd(W));
135 LibmeshPetscCall(SNESComputeFunction(snes, W,
F));
136 #if PETSC_VERSION_LESS_THAN(3, 25, 0) 137 PetscBool domainerror;
138 LibmeshPetscCall(SNESGetFunctionDomainError(snes, &domainerror));
140 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_FAILED_DOMAIN));
142 SNESConvergedReason reason;
143 LibmeshPetscCall(SNESGetConvergedReason(snes, &reason));
144 if (reason == SNES_DIVERGED_FUNCTION_DOMAIN)
145 LibmeshPetscCall(SNESLineSearchSetReason(line_search, SNES_LINESEARCH_FAILED_FUNCTION_DOMAIN));
148 LibmeshPetscCall(VecNorm(
F, NORM_2, &fnorm));
150 LibmeshPetscCall(VecCopy(W,
X));
152 LibmeshPetscCall(SNESLineSearchComputeNorms(line_search));
virtual MooseMesh & mesh() override
SNES snes(const char *name=nullptr)
virtual libMesh::NonlinearSolver< Number > * nonlinearSolver() override
virtual GeometricSearchData & geomSearchData() override
NonlinearSystemBase & _nl
registerMooseObject("ContactApp", PetscProjectSolutionOntoBounds)
static const std::string component
const Parallel::Communicator & comm() const
void setSolution(const NumericVector< Number > &soln)
static const std::string F
unsigned int variable_number(std::string_view var) const
static const std::string G
Petsc implementation of the contact line search (based on the Petsc LineSearchShell) ...
PetscProjectSolutionOntoBounds(const InputParameters ¶meters)
PetscNonlinearSolver< Real > * _solver
static InputParameters validParams()
const std::vector< std::string > & getDisplacementVarNames() const
const std::map< std::pair< BoundaryID, BoundaryID >, PenetrationLocator *> & getPenetrationLocators() const
virtual std::shared_ptr< const DisplacedProblem > getDisplacedProblem() const
void mooseError(Args &&... args) const
void initialSetup() override
virtual void updateMesh(bool mesh_changing=false)
processor_id_type processor_id() const
virtual NonlinearSystem & getNonlinearSystem(const unsigned int nl_sys_num) override
virtual void lineSearch() override
static InputParameters validParams()
DisplacedProblem * _displaced_problem
virtual libMesh::System & system() override