33 #ifndef __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__NEWTON_SOLVER__NEWTON_IMPL__
34 #define __H__UG__LIB_DISC__OPERATOR__NON_LINEAR_OPERATOR__NEWTON_SOLVER__NEWTON_IMPL__
44 #include "lib_disc/operator/non_linear_operator/newton_solver/nestedNewtonRFSwitch.h"
46 #define PROFILE_NEWTON
48 #define NEWTON_PROFILE_FUNC() PROFILE_FUNC_GROUP("Newton")
49 #define NEWTON_PROFILE_BEGIN(name) PROFILE_BEGIN_GROUP(name, "Newton")
50 #define NEWTON_PROFILE_END() PROFILE_END()
52 #define NEWTON_PROFILE_FUNC()
53 #define NEWTON_PROFILE_BEGIN(name)
54 #define NEWTON_PROFILE_END()
59 template <
typename TAlgebra>
65 m_spConvCheck(spConvCheck),
66 m_spLineSearch(spLineSearch),
70 m_reassembe_J_freq(0),
73 #
if ENABLE_NESTED_NEWTON_RESOLFUNC_UPDATE
79 template <
typename TAlgebra>
82 m_spLinearSolver(NULL),
88 m_reassembe_J_freq(0),
91 #
if ENABLE_NESTED_NEWTON_RESOLFUNC_UPDATE
97 template <
typename TAlgebra>
100 m_spLinearSolver(NULL),
102 m_spLineSearch(NULL),
106 m_reassembe_J_freq(0),
109 #
if ENABLE_NESTED_NEWTON_RESOLFUNC_UPDATE
117 template <
typename TAlgebra>
120 m_spLinearSolver(NULL),
122 m_spLineSearch(NULL),
126 m_reassembe_J_freq(0),
129 #
if ENABLE_NESTED_NEWTON_RESOLFUNC_UPDATE
138 template <
typename TAlgebra>
142 m_spConvCheck = spConvCheck;
143 m_spConvCheck->set_offset(3);
144 m_spConvCheck->set_symbol(
'#');
145 m_spConvCheck->set_name(
"Newton Solver");
148 template <
typename TAlgebra>
152 m_N = N.template cast_dynamic<AssembledOperator<TAlgebra> >();
154 UG_THROW(
"NewtonSolver: currently only works for AssembledDiscreteOperator.");
156 m_spAss = m_N->discretization();
160 template <
typename TAlgebra>
167 template <
typename TAlgebra>
175 if(m_spLinearSolver.invalid())
176 UG_THROW(
"NewtonSolver::apply: Linear Solver not set.");
179 if(m_J.invalid() || m_J->discretization() != m_spAss) {
182 m_J->set_level(m_N->level());
192 UG_CATCH_THROW(
"NewtonSolver::prepare: Prepare of Operator failed.");
199 }
UG_CATCH_THROW(
"NewtonSolver::apply: Computation of Start-Defect failed.");
206 char debug_name_ext[20];
207 if (this->debug_writer_valid())
209 snprintf(debug_name_ext, 20,
"_iter%03d", loopCnt);
210 write_debug(*spD, std::string(
"NEWTON_Defect") + debug_name_ext);
211 write_debug(u,
"NEWTON_StartSolution");
215 const int stdLinOffset = m_spLinearSolver->standard_offset();
216 m_spLinearSolver->convergence_check()->set_offset(stdLinOffset + 3);
219 std::stringstream ss; ss <<
"(Linear Solver: " << m_spLinearSolver->name() <<
")";
220 m_spConvCheck->set_info(ss.str());
223 m_spConvCheck->start(*spD);
225 for(
size_t i = 0; i < m_stepUpdate.size(); ++i)
226 m_stepUpdate[i]->update();
229 while(!m_spConvCheck->iteration_ended())
231 m_lastNumSteps = loopCnt;
238 for(
size_t i = 0; i < m_innerStepUpdate.size(); ++i)
239 m_innerStepUpdate[i]->update();
243 if(m_reassembe_J_freq == 0 || loopCnt % m_reassembe_J_freq == 0)
249 }
UG_CATCH_THROW(
"NewtonSolver::apply: Initialization of Jacobian failed.");
252 if (this->debug_writer_valid())
254 write_debug(m_J->get_matrix(), std::string(
"NEWTON_Jacobian") + debug_name_ext);
255 this->enter_debug_writer_section(std::string(
"NEWTON_LinSolver") + debug_name_ext);
261 if(!m_spLinearSolver->init(m_J, u))
263 UG_LOG(
"ERROR in 'NewtonSolver::apply': Cannot init Inverse Linear "
264 "Operator for Jacobi-Operator.\n");
268 }
UG_CATCH_THROW(
"NewtonSolver::apply: Initialization of Linear Solver failed.");
273 if(!m_spLinearSolver->apply(*spC, *spD))
275 UG_LOG(
"ERROR in 'NewtonSolver::apply': Cannot apply Inverse Linear "
276 "Operator for Jacobi-Operator.\n");
280 }
UG_CATCH_THROW(
"NewtonSolver::apply: Application of Linear Solver failed.");
282 this->leave_debug_writer_section();
285 const int numSteps = m_spLinearSolver->step();
286 if(loopCnt >= (
int)m_vTotalLinSolverSteps.size()) m_vTotalLinSolverSteps.resize(loopCnt+1);
287 if(loopCnt >= (
int)m_vLinSolverCalls.size()) m_vLinSolverCalls.resize(loopCnt+1, 0);
288 if(loopCnt >= (
int)m_vLinSolverRates.size()) m_vLinSolverRates.resize(loopCnt+1, 0);
289 m_vTotalLinSolverSteps[loopCnt] += numSteps;
290 m_vLinSolverCalls[loopCnt] += 1;
291 m_vLinSolverRates[loopCnt] += m_spLinearSolver->convergence_check()->avg_rate();
295 if(m_spLineSearch.valid())
297 m_spLineSearch->set_offset(
" # ");
300 #if ENABLE_NESTED_NEWTON_RESOLFUNC_UPDATE
302 m_spLineSearch->setNewtonUpdater(m_newtonUpdater);
305 if(!m_spLineSearch->search(m_N, u, *spC, *spD, m_spConvCheck->defect()))
307 UG_LOG(
"ERROR in 'NewtonSolver::apply': "
308 "Newton Solver did not converge.\n");
316 #if ENABLE_NESTED_NEWTON_RESOLFUNC_UPDATE
325 if( ! m_newtonUpdater->updateSolution(u,*spC) )
327 UG_LOG(
"ERROR in 'NewtonSolver::apply': "
328 "Newton Update did not work.\n");
333 if( ! m_newtonUpdater->tellAndFixUpdateEvents(u) )
335 UG_LOG(
"unable to fix local Newton updates" << std::endl );
351 }
UG_CATCH_THROW(
"NewtonSolver::apply: Line Search update failed.");
358 m_spConvCheck->update(*spD);
359 if(loopCnt-1 >= (
int)m_vNonLinSolverRates.size()) m_vNonLinSolverRates.resize(loopCnt, 0);
360 m_vNonLinSolverRates[loopCnt-1] += m_spConvCheck->rate();
363 if (this->debug_writer_valid())
365 snprintf(debug_name_ext, 20,
"_iter%03d", loopCnt);
366 write_debug(*spD, std::string(
"NEWTON_Defect") + debug_name_ext);
367 write_debug(*spC, std::string(
"NEWTON_Correction") + debug_name_ext);
368 write_debug(u, std::string(
"NEWTON_Solution") + debug_name_ext);
373 m_spLinearSolver->convergence_check()->set_offset(stdLinOffset);
375 return m_spConvCheck->post();
378 template <
typename TAlgebra>
381 UG_LOG(
"\nNewton solver convergence history:\n");
382 UG_LOG(
"Newton Step | Num Calls | Total Lin Iters | Avg Lin Iters | Avg Nonlin Rates | Avg Lin Rates \n");
383 int allCalls = 0, allLinSteps = 0;
384 number allLinRatesProduct = 1.0, allNonLinRatesProduct = 1.0;
385 for(
int call = 0; call < (int)m_vLinSolverCalls.size(); ++call)
387 UG_LOG(
" " << std::setw(10) << call+1 <<
" | ");
388 UG_LOG(std::setw(9) << m_vLinSolverCalls[call] <<
" | ");
389 allCalls += m_vLinSolverCalls[call];
390 UG_LOG(std::setw(15) << m_vTotalLinSolverSteps[call] <<
" | ");
391 allLinSteps += m_vTotalLinSolverSteps[call];
392 UG_LOG(std::setw(13) << std::setprecision(2) << std::fixed << m_vTotalLinSolverSteps[call] / (
double)m_vLinSolverCalls[call] <<
" | ");
393 allNonLinRatesProduct *= pow((
number)m_vNonLinSolverRates[call]/(
double)m_vLinSolverCalls[call],(
double)m_vLinSolverCalls[call]);
394 UG_LOG(std::setw(16) << std::setprecision(6) << std::scientific << m_vNonLinSolverRates[call] / (
double)m_vLinSolverCalls[call] <<
" | ");
395 allLinRatesProduct *= (
number)std::pow((
number)m_vLinSolverRates[call]/(double)m_vLinSolverCalls[call],(
number)m_vTotalLinSolverSteps[call]);
396 UG_LOG(std::setw(13) << std::setprecision(6) << std::scientific << m_vLinSolverRates[call] / (
double)m_vLinSolverCalls[call]);
400 UG_LOG(std::setw(9) << allCalls <<
" | ");
401 UG_LOG(std::setw(15) << allLinSteps <<
" | ");
402 UG_LOG(std::setw(13) << std::setprecision(2) << std::fixed << allLinSteps / (
number)allCalls <<
" | ");
403 UG_LOG(std::setw(16) << std::setprecision(6) << std::scientific << std::pow((
number)allNonLinRatesProduct,(
number)1.0/(
number)allCalls) <<
" | ");
404 UG_LOG(std::setw(13) << std::setprecision(6) << std::scientific << std::pow((
number)allLinRatesProduct,(
number)1.0/(
number)allLinSteps));
408 template <
typename TAlgebra>
411 return m_vLinSolverCalls.size();
414 template <
typename TAlgebra>
417 return m_vLinSolverCalls[call];
420 template <
typename TAlgebra>
423 return m_vTotalLinSolverSteps[call];
426 template <
typename TAlgebra>
429 return m_vTotalLinSolverSteps[call] / ((double)m_vLinSolverCalls[call]);
432 template <
typename TAlgebra>
436 for(
size_t call = 0; call < m_vLinSolverCalls.size(); ++call)
437 allCalls += m_vLinSolverCalls[call];
441 template <
typename TAlgebra>
445 for(
size_t call = 0; call < m_vLinSolverCalls.size(); ++call)
446 allSteps += m_vTotalLinSolverSteps[call];
450 template <
typename TAlgebra>
453 return total_linsolver_steps()/((double)total_linsolver_calls());
457 template <
typename TAlgebra>
460 m_vLinSolverRates.clear();
461 m_vNonLinSolverRates.clear();
462 m_vLinSolverCalls.clear();
463 m_vTotalLinSolverSteps.clear();
466 template <
typename TAlgebra>
470 char ext[20]; snprintf(ext, 20,
"_call%03d", m_dgbCall);
474 base_writer_type::write_debug(vec,
name + ext);
477 template <
typename TAlgebra>
481 char ext[20]; snprintf(ext, 20,
"_call%03d", m_dgbCall);
485 base_writer_type::write_debug(mat,
name + ext);
488 template <
typename TAlgebra>
491 std::stringstream ss;
492 ss <<
"NewtonSolver\n";
493 ss <<
" LinearSolver: ";
494 if(m_spLinearSolver.valid()) ss <<
ConfigShift(m_spLinearSolver->config_string()) <<
"\n";
495 else ss <<
" NOT SET!\n";
496 ss <<
" ConvergenceCheck: ";
497 if(m_spConvCheck.valid()) ss <<
ConfigShift(m_spConvCheck->config_string()) <<
"\n";
498 else ss <<
" NOT SET!\n";
499 ss <<
" LineSearch: ";
500 if(m_spLineSearch.valid()) ss <<
ConfigShift(m_spLineSearch->config_string()) <<
"\n";
501 else ss <<
" not set.\n";
502 if(m_reassembe_J_freq != 0) ss <<
" Reassembling Jacobian only once per " << m_reassembe_J_freq <<
" step(s)\n";
location name
Definition: checkpoint_util.lua:128
Definition: smart_pointer.h:108
matrix operator based on the assembling of a problem
Definition: assembled_linear_operator.h:60
Definition: assembled_non_linear_operator.h:43
Definition: debug_writer.h:354
TAlgebra::vector_type vector_type
type of vector
Definition: debug_writer.h:360
TAlgebra::matrix_type matrix_type
type of matrix
Definition: debug_writer.h:363
Interface providing Jacobian and Defect of a discretization.
Definition: assemble_interface.h:110
Definition: convergence_check.h:72
Definition: line_search.h:71
describes an inverse linear mapping X->Y
Definition: linear_operator_inverse.h:80
describes a mapping X->Y
Definition: operator.h:86
linear solver using abstract preconditioner interface
Definition: linear_solver.h:57
int total_linsolver_calls() const
Definition: newton_impl.h:433
void clear_average_convergence()
resets average linear solver convergence
Definition: newton_impl.h:458
virtual bool prepare(vector_type &u)
prepare Operator
Definition: newton_impl.h:161
virtual bool apply(vector_type &u)
apply Operator, i.e. N^{-1}(0) = u
Definition: newton_impl.h:168
NewtonSolver()
default constructor
Definition: newton_impl.h:81
virtual bool init(SmartPtr< IOperator< vector_type > > N)
This operator inverts the Operator N: Y -> X.
Definition: newton_impl.h:149
int num_linsolver_steps(size_t call) const
Definition: newton_impl.h:421
void write_debug(const vector_type &vec, std::string filename)
Definition: newton_impl.h:467
double total_average_linear_steps() const
Definition: newton_impl.h:451
virtual std::string config_string() const
returns information about configuration parameters
Definition: newton_impl.h:489
double average_linear_steps(size_t call) const
Definition: newton_impl.h:427
void print_average_convergence() const
prints average linear solver convergence
Definition: newton_impl.h:379
size_t num_newton_steps() const
Definition: newton_impl.h:409
void set_convergence_check(SmartPtr< IConvergenceCheck< vector_type > > spConvCheck)
sets the convergence check
Definition: newton_impl.h:140
int num_linsolver_calls(size_t call) const
Definition: newton_impl.h:415
int total_linsolver_steps() const
Definition: newton_impl.h:442
Definition: newtonUpdaterGeneric.h:25
Definition: convergence_check.h:179
#define UG_CATCH_THROW(msg)
Definition: error.h:64
#define UG_THROW(msg)
Definition: error.h:57
#define UG_LOG(msg)
Definition: log.h:367
double number
Definition: types.h:124
if(!(yy_init))
Definition: lexer.cpp:997
string ConfigShift(string s)
Definition: string_util.cpp:457
#define NEWTON_PROFILE_END()
Definition: newton_impl.h:50
#define NEWTON_PROFILE_BEGIN(name)
Definition: newton_impl.h:49
SmartPtr< T, FreePolicy > make_sp(T *inst)
returns a SmartPtr for the passed raw pointer
Definition: smart_pointer.h:836
function ProblemDisc new(problemDesc, dom)