17 #ifdef D2K_WITH_SUNDIALS 22 #ifdef DEAL_II_WITH_PETSC 24 #ifdef DEAL_II_WITH_MPI 29 #ifdef DEAL_II_WITH_TRILINOS 31 #ifdef DEAL_II_WITH_MPI 37 #include <kinsol/kinsol_dense.h> 46 template<
typename VEC>
47 int kinsol_residual( N_Vector y, N_Vector res,
void *user_data)
59 int ret = solver.
residual(*loc_y, *loc_res);
66 template<
typename VEC>
67 int kinsol_setup_jacobian( KINMem kin_mem )
73 copy( *loc_y, kin_mem->kin_uu );
79 template<
typename VEC>
80 int kinsol_solve_linear_system(KINMem kin_mem,
94 copy( *loc_res, kin_mem->kin_fval);
103 *sJpnorm = N_VWL2Norm(b, kin_mem->kin_fscale);
104 N_VProd(b, kin_mem->kin_fscale, b);
105 N_VProd(b, kin_mem->kin_fscale, b);
106 *sFdotJp = N_VDotProd(kin_mem->kin_fval, b);
113 template <
typename VEC>
117 create_new_vector = []() ->shared_ptr<VEC>
124 residual = [](
const VEC &, VEC &) ->
int 131 setup_jacobian = [](
const VEC &) ->
int 138 solve_linear_system = [](
const VEC &, VEC &) ->
int 145 jacobian_vmult = [](
const VEC &, VEC &) ->
int 155 #ifdef DEAL_II_WITH_MPI 158 template <
typename VEC>
160 const MPI_Comm mpi_comm):
162 is_initialized(
false),
163 scaling_is_set(
false),
168 set_functions_to_trigger_an_assert();
173 template <
typename VEC>
176 is_initialized(false),
186 template <
typename VEC>
194 template <
typename VEC>
199 "Maximum number of iterations",
"200",
201 "The non-linear solver will stop when reaching this number of" 202 "Newton iterations no matter what.");
205 "Tolerance for residuals",
"1e-9",
207 "This define the condition (small residual) for a successful completion of KINSOL.\n" 208 " 0 means the default value for KINSOL");
211 "Step tolerance",
"1e-11",
213 "The Newton method will terminate when the maximum scaled step is below the given tolerance." );
217 "Allowed values [0,3]");
221 "newton = basic Newton iteration \n" 222 "global_newton = Newton with line search \n" 223 "fixed_point = fixed-point iteration with Anderson Acceleration \n" 224 "picard = Picard iteration with Anderson Acceleration");
227 "Maximum number of iteration before Jacobian update",
"10",
229 "Maximum number of nonlinear iterations that can be done with an outdated Jacobian.\n" 230 "If set to 1 the Jacobian is updated at each nonlinear iteration");
233 "Use internal KINSOL direct solver",
"false",
235 "If true the dense direct linear solver of KINSOL is used");
240 template <
typename VEC>
253 kin_mem = KINCreate();
259 #ifdef DEAL_II_WITH_MPI 260 IndexSet is = initial_guess.locally_owned_elements();
271 status = KINSetUserData(kin_mem, (
void *)
this);
272 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error initializing KINSOL. KINInit failed."));
276 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error initializing KINSOL. KINSetNumMaxIters failed."));
279 status = KINSetFuncNormTol(kin_mem,
ftol);
280 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error initializing KINSOL. KINSetFuncNormTol failed."));
283 status = KINSetScaledStepTol(kin_mem,
steptol);
284 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error initializing KINSOL. KINSetFuncNormTol failed."));
287 status = KINInit(kin_mem, kinsol_residual<VEC> ,
solution);
288 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error initializing KINSOL. KINInit failed."));
291 status = KINSetPrintLevel(kin_mem,
verbosity);
292 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error intializing KINSOL. KINSetPrintLevel failed."));
294 status = KINSetMaxSetupCalls(kin_mem,
mbset);
295 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error intializing KINSOL. KINSetMaxSetupCalls failed."));
303 KIN_mem = (KINMem) kin_mem;
304 KIN_mem->kin_lsetup = kinsol_setup_jacobian<VEC>;
305 KIN_mem->kin_lsolve = kinsol_solve_linear_system<VEC>;
306 KIN_mem->kin_setupNonNull =
true;
314 template <
typename VEC>
327 #ifdef DEAL_II_WITH_MPI 329 N_VConst_Parallel( 1.e0,
u_scale );
331 N_VConst_Parallel( 1.e0,
f_scale );
335 N_VConst_Serial( 1.e0,
u_scale );
337 N_VConst_Serial( 1.e0,
f_scale );
352 if (status == KIN_MXNEWT_5X_EXCEEDED)
364 KIN_mem = (KINMem) kin_mem;
365 copy(*res, KIN_mem->kin_fval);
366 KINSetMaxNewtonStep(kin_mem, res->l2_norm());
368 pcout <<
"Don't worry. This might be only a problem of scaling... Let's try." 377 AssertThrow(status >= 0 ,
ExcMessage(
"KINSOL did not converge. You might try with a different strategy."));
384 template <
typename VEC>
390 ExcMessage(
"KINSOLInterface is not initialized when " 391 "calling set_scaling_vectors!\n" 392 "you need to call initialize_solver() first " 393 "in order to make kinsol aware of the dimension of the system."));
395 #ifdef DEAL_II_WITH_MPI 410 template <
typename VEC>
417 ExcMessage(
"KINSOLInterface is not initialized " 418 "when calling initialize_constraint_vector!"));
420 #ifdef DEAL_II_WITH_MPI 421 N_Vector constraint_v = N_VNew_Parallel(communicator, local_system_size,
system_size);
423 N_Vector constraint_v = N_VNew_Serial(
system_size);
425 copy(constraint_v, constraint );
427 status = KINSetConstraints( kin_mem, constraint_v);
429 Assert(status == KIN_SUCCESS,
ExcMessage(
"Error initializing KINSOL. KINSetConstraints in initialize_constraint_vector failed."));
436 template class deal2lkit::KINSOLInterface<BlockVector<double> >;
438 #ifdef DEAL_II_WITH_MPI 440 #ifdef DEAL_II_WITH_TRILINOS 441 template class deal2lkit::KINSOLInterface<TrilinosWrappers::MPI::Vector>;
442 template class deal2lkit::KINSOLInterface<TrilinosWrappers::MPI::BlockVector>;
445 #ifdef DEAL_II_WITH_PETSC 446 template class deal2lkit::KINSOLInterface<PETScWrappers::MPI::Vector>;
447 template class deal2lkit::KINSOLInterface<PETScWrappers::MPI::BlockVector>;
N_Vector solution
KINSOL solution vector.
static::ExceptionBase & ExcPureFunctionCalled()
unsigned int system_size
dimension of the system
A parameter acceptor base class.
static ParameterHandler prm
Static parameter.
bool use_internal_solver
if true the internal direct solver of KINSOL is used.
double steptol
The Newton method will terminate when the scaled norm of the update is smaller than steptol...
void set_scaling_vectors(const VEC &uscale, const VEC &fscale)
Set the scaling for the solver.
void copy(BlockVector< double > &dst, const N_Vector &src)
size_type n_elements() const
std::function< int(const VEC &v, VEC &dst)> jacobian_vmult
standard function multiplying the Jacobian to a vector
std::function< int(const VEC &y, VEC &res)> residual
standard function computing residuals
void set_functions_to_trigger_an_assert()
This function is executed at construction time to set the std::function above to trigger an assert if...
#define AssertThrow(cond, exc)
unsigned int max_iterations
Maximum number of iterations.
double ftol
Input scalar tolerance for residuals.
std::function< shared_ptr< VEC >)> create_new_vector
this function has to be implemented by the user and it must return a shared pointer to a VEC vector...
static::ExceptionBase & ExcMessage(std::string arg1)
Interface to SUNDIALS KINSOL library.
unsigned int verbosity
Level of verbosity of kinsol solver 0,1,2,3.
ConditionalOStream pcout
Output stream.
void set_constraint_vector(const VEC &constraint)
Set the constraint.
#define Assert(cond, exc)
std::string strategy
Strategy used by the solver: newton = basic Newton iteration global_newton = Newton with line search ...
std::function< int(const VEC &y)> setup_jacobian
standard function computing the Jacobian
KINSOLInterface(const std::string name="")
Constructor for the KINSOLInterface class.
void initialize_solver(VEC &initial_guess)
Initializes the solver with the initial guess and the residual function.
virtual void declare_parameters(ParameterHandler &prm)
Declare parameters for this class to function properly.
N_Vector f_scale
Internal scaling vector for the Jacobian.
std::function< int(const VEC &res, VEC &dst)> solve_linear_system
standard function solving linear system
~KINSOLInterface()
House cleaning.
bool scaling_is_set
scaling flag: if the scaling have been provided by the user calling the function set_scaling_vectors(...
MPI_Comm duplicate_communicator(const MPI_Comm &mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
bool is_initialized
Initialization flag.
N_Vector u_scale
Internal scaling vector for the solution.
int solve(VEC &solution)
solve the non-linear system
void add_parameter(ParameterHandler &prm, T *parameter, const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
Add a parameter the given parameter list.
double mbset
Maximum number of nonlinear iteration that can be done without a Jacobian update. ...