26 std::vector<GlobalVector*>&
x;
27 std::vector<GlobalVector*>
const&
x_prev;
34 SNESConvergedReason
const& reason)
36 const char* strreason;
37 SNESGetConvergedReasonString(snes_solver, &strreason);
40 INFO(
"PETScSNES diverged reason: {:s}.", strreason);
44 INFO(
"PETScSNES converged reason: {:s}.", strreason);
51 auto context =
static_cast<PetscContext*
>(petsc_context);
53 DBUG(
"PETScNonlinearSolver: residual callback called.");
55 VecCopy(x, context->x[context->process_id]->getRawVector());
59 time_assembly.
start();
60 context->system->assemble(context->x, context->x_prev, context->process_id);
62 INFO(
"[time] Assembly took {} s.", time_assembly.
elapsed());
63 context->system->getResidual(*context->x[context->process_id],
64 *context->x_prev[context->process_id],
66 context->r->finalizeAssembly();
67 context->J->finalizeAssembly();
69 context->system->getJacobian(*context->J);
70 context->system->applyKnownSolutionsPETScSNES(
71 *context->J, *context->r, *context->x[context->process_id]);
73 VecCopy(context->r->getRawVector(), petsc_r);
79 Mat ,
void* petsc_context)
81 DBUG(
"PETScNonlinearSolver: jacobian callback called.");
85 auto context =
static_cast<PetscContext*
>(petsc_context);
86 MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY);
87 MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY);
88 MatCopy(context->J->getRawMatrix(), J, DIFFERENT_NONZERO_PATTERN);
102 prefix = prefix +
"_";
110 PetscReal atol, rtol, stol;
112 SNESGetTolerances(
_snes_solver, &atol, &rtol, &stol,
nullptr, &maxf);
113 SNESSetTolerances(
_snes_solver, atol, rtol, stol, maxiter, maxf);
117 PetscOptionsView(
nullptr, PETSC_VIEWER_STDOUT_WORLD);
135 std::vector<GlobalVector*>
const& ,
136 std::vector<GlobalVector*>
const& ,
int const )
144 "Non-equilibrium initial residuum is not implemented for the "
145 "PETScNonlinearSolver.");
149 std::vector<GlobalVector*>& x,
150 std::vector<GlobalVector*>
const& x_prev,
153 std::vector<GlobalVector*>
const&)>
const& ,
154 int const process_id)
156 DBUG(
"PETScNonlinearSolver: solve()");
157 using TimeDiscretizedSystem =
163 DBUG(
"PETScNonlinearSolver: create vectors");
166 system->getMatrixSpecifications(process_id),
_jacobian_id);
168 system->getMatrixSpecifications(process_id),
_residual_id);
175 double time_dirichlet = 0.0;
177 timer_dirichlet.
start();
178 system->computeKnownSolutions(*x[process_id], process_id);
179 system->applyKnownSolutions(*x[process_id]);
180 time_dirichlet += timer_dirichlet.
elapsed();
181 INFO(
"[time] Applying Dirichlet BCs took {} s.", time_dirichlet);
186 system->getMatrixSpecifications(process_id),
_petsc_x_id);
189 PetscContext petsc_context{
_equation_system, x, x_prev, &r, &J, process_id};
191 DBUG(
"PETScNonlinearSolver: set function");
192 SNESSetFunction(
_snes_solver, r_snes.getRawVector(), updateResidual,
195 DBUG(
"PETScNonlinearSolver: set jacobian");
197 SNESSetJacobian(
_snes_solver, J_snes.getRawMatrix(), J_snes.getRawMatrix(),
198 updateJacobian, &petsc_context);
200 std::unique_ptr<GlobalVector> xl =
nullptr;
201 std::unique_ptr<GlobalVector> xu =
nullptr;
205 if ((std::strcmp(snes_type, SNESVINEWTONRSLS) == 0) ||
206 (std::strcmp(snes_type, SNESVINEWTONSSLS) == 0))
209 DBUG(
"PETScNonlinearSolver: set constraints");
211 system->getMatrixSpecifications(process_id));
213 system->getMatrixSpecifications(process_id));
215 system->updateConstraints(*xl, *xu, process_id);
219 SNESVISetVariableBounds(
_snes_solver, xl->getRawVector(),
223 DBUG(
"PETScNonlinearSolver: call SNESSolve");
224 SNESSolve(
_snes_solver,
nullptr, x_snes.getRawVector());
226 SNESConvergedReason reason;
232 INFO(
"PETScSNES used {} iterations.", iterations);
243 return {reason >= 0, iterations};
void INFO(fmt::format_string< Args... > fmt, Args &&... args)
void DBUG(fmt::format_string< Args... > fmt, Args &&... args)
Definition of the RunTime class.
double elapsed() const
Get the elapsed time in seconds.
void start()
Start the timer.
Global vector based on Eigen vector.
virtual void releaseMatrix(GlobalMatrix const &A)=0
virtual GlobalMatrix & getMatrix(std::size_t &id)=0
Get an uninitialized matrix with the given id.
std::size_t _petsc_residual_id
ConvergenceCriterion * _convergence_criterion
NonlinearSolverStatus solve(std::vector< GlobalVector * > &x, std::vector< GlobalVector * > const &x_prev, std::function< void(int, std::vector< GlobalVector * > const &)> const &postIterationCallback, int const process_id) override
std::size_t _petsc_jacobian_id
System * _equation_system
void setEquationSystem(System &eq, ConvergenceCriterion &conv_crit)
Set the nonlinear equation system that will be solved.
PETScNonlinearSolver(GlobalLinearSolver &linear_solver, int maxiter, std::string prefix)
bool _compensate_non_equilibrium_initial_residuum
std::size_t _jacobian_id
ID of the Jacobian matrix.
void compensateNonEquilibriumInitialResiduum(bool const value)
std::size_t _residual_id
ID of the residual vector.
void calculateNonEquilibriumInitialResiduum(std::vector< GlobalVector * > const &x, std::vector< GlobalVector * > const &x_prev, int const process_id) override
virtual GlobalVector & getVector(std::size_t &id)=0
Get an uninitialized vector with the given id.
virtual void releaseVector(GlobalVector const &x)=0
@ FirstOrderImplicitQuasilinear
void copy(PETScVector const &x, PETScVector &y)
void finalizeVectorAssembly(VEC_T &)
General function to finalize the vector assembly.
PetscErrorCode updateResidual(SNES, Vec x, Vec petsc_r, void *petsc_context)
void printConvergenceReason(SNES const &snes_solver, SNESConvergedReason const &reason)
PetscErrorCode updateJacobian(SNES, Vec, Mat J, Mat, void *petsc_context)
static NUMLIB_EXPORT MatrixProvider & provider
static NUMLIB_EXPORT VectorProvider & provider
Status of the non-linear solver.
std::vector< GlobalVector * > & x
std::vector< GlobalVector * > const & x_prev