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__
43 #define PROFILE_NEWTON
45 #define NEWTON_PROFILE_FUNC() PROFILE_FUNC_GROUP("Newton")
46 #define NEWTON_PROFILE_BEGIN(name) PROFILE_BEGIN_GROUP(name, "Newton")
47 #define NEWTON_PROFILE_END() PROFILE_END()
49 #define NEWTON_PROFILE_FUNC()
50 #define NEWTON_PROFILE_BEGIN(name)
51 #define NEWTON_PROFILE_END()
56 template <
typename TAlgebra>
62 m_spConvCheck(spConvCheck),
63 m_spLineSearch(spLineSearch),
67 m_reassembe_J_freq(0),
72 template <
typename TAlgebra>
75 m_spLinearSolver(NULL),
81 m_reassembe_J_freq(0),
86 template <
typename TAlgebra>
89 m_spLinearSolver(NULL),
95 m_reassembe_J_freq(0),
102 template <
typename TAlgebra>
105 m_spLinearSolver(NULL),
107 m_spLineSearch(NULL),
111 m_reassembe_J_freq(0),
119 template <
typename TAlgebra>
123 m_spConvCheck = spConvCheck;
124 m_spConvCheck->set_offset(3);
125 m_spConvCheck->set_symbol(
'#');
126 m_spConvCheck->set_name(
"Newton Solver");
129 template <
typename TAlgebra>
133 m_N = N.template cast_dynamic<AssembledOperator<TAlgebra> >();
135 UG_THROW(
"NewtonSolver: currently only works for AssembledDiscreteOperator.");
137 m_spAss = m_N->discretization();
141 template <
typename TAlgebra>
148 template <
typename TAlgebra>
156 if(m_spLinearSolver.invalid())
157 UG_THROW(
"NewtonSolver::apply: Linear Solver not set.");
160 if(m_J.invalid() || m_J->discretization() != m_spAss) {
163 m_J->set_level(m_N->level());
173 UG_CATCH_THROW(
"NewtonSolver::prepare: Prepare of Operator failed.");
180 }
UG_CATCH_THROW(
"NewtonSolver::apply: Computation of Start-Defect failed.");
187 char debug_name_ext[20];
188 if (this->debug_writer_valid())
190 snprintf(debug_name_ext, 20,
"_iter%03d", loopCnt);
191 write_debug(*spD, std::string(
"NEWTON_Defect") + debug_name_ext);
192 write_debug(u,
"NEWTON_StartSolution");
196 const int stdLinOffset = m_spLinearSolver->standard_offset();
197 m_spLinearSolver->convergence_check()->set_offset(stdLinOffset + 3);
200 std::stringstream ss; ss <<
"(Linear Solver: " << m_spLinearSolver->name() <<
")";
201 m_spConvCheck->set_info(ss.str());
204 m_spConvCheck->start(*spD);
206 for(
size_t i = 0; i < m_stepUpdate.size(); ++i)
207 m_stepUpdate[i]->update();
210 while(!m_spConvCheck->iteration_ended())
212 m_lastNumSteps = loopCnt;
219 for(
size_t i = 0; i < m_innerStepUpdate.size(); ++i)
220 m_innerStepUpdate[i]->update();
224 if(m_reassembe_J_freq == 0 || loopCnt % m_reassembe_J_freq == 0)
230 }
UG_CATCH_THROW(
"NewtonSolver::apply: Initialization of Jacobian failed.");
233 if (this->debug_writer_valid())
235 write_debug(m_J->get_matrix(), std::string(
"NEWTON_Jacobian") + debug_name_ext);
236 this->enter_debug_writer_section(std::string(
"NEWTON_LinSolver") + debug_name_ext);
242 if(!m_spLinearSolver->init(m_J, u))
244 UG_LOG(
"ERROR in 'NewtonSolver::apply': Cannot init Inverse Linear "
245 "Operator for Jacobi-Operator.\n");
249 }
UG_CATCH_THROW(
"NewtonSolver::apply: Initialization of Linear Solver failed.");
254 if(!m_spLinearSolver->apply(*spC, *spD))
256 UG_LOG(
"ERROR in 'NewtonSolver::apply': Cannot apply Inverse Linear "
257 "Operator for Jacobi-Operator.\n");
261 }
UG_CATCH_THROW(
"NewtonSolver::apply: Application of Linear Solver failed.");
263 this->leave_debug_writer_section();
266 const int numSteps = m_spLinearSolver->step();
267 if(loopCnt >= (
int)m_vTotalLinSolverSteps.size()) m_vTotalLinSolverSteps.resize(loopCnt+1);
268 if(loopCnt >= (
int)m_vLinSolverCalls.size()) m_vLinSolverCalls.resize(loopCnt+1, 0);
269 if(loopCnt >= (
int)m_vLinSolverRates.size()) m_vLinSolverRates.resize(loopCnt+1, 0);
270 m_vTotalLinSolverSteps[loopCnt] += numSteps;
271 m_vLinSolverCalls[loopCnt] += 1;
272 m_vLinSolverRates[loopCnt] += m_spLinearSolver->convergence_check()->avg_rate();
276 if(m_spLineSearch.valid())
278 m_spLineSearch->set_offset(
" # ");
280 if(!m_spLineSearch->search(m_N, u, *spC, *spD, m_spConvCheck->defect()))
282 UG_LOG(
"ERROR in 'NewtonSolver::apply': "
283 "Newton Solver did not converge.\n");
300 }
UG_CATCH_THROW(
"NewtonSolver::apply: Line Search update failed.");
307 m_spConvCheck->update(*spD);
308 if(loopCnt-1 >= (
int)m_vNonLinSolverRates.size()) m_vNonLinSolverRates.resize(loopCnt, 0);
309 m_vNonLinSolverRates[loopCnt-1] += m_spConvCheck->rate();
312 if (this->debug_writer_valid())
314 snprintf(debug_name_ext, 20,
"_iter%03d", loopCnt);
315 write_debug(*spD, std::string(
"NEWTON_Defect") + debug_name_ext);
316 write_debug(*spC, std::string(
"NEWTON_Correction") + debug_name_ext);
317 write_debug(u, std::string(
"NEWTON_Solution") + debug_name_ext);
322 m_spLinearSolver->convergence_check()->set_offset(stdLinOffset);
324 return m_spConvCheck->post();
327 template <
typename TAlgebra>
330 UG_LOG(
"\nNewton solver convergence history:\n");
331 UG_LOG(
"Newton Step | Num Calls | Total Lin Iters | Avg Lin Iters | Avg Nonlin Rates | Avg Lin Rates \n");
332 int allCalls = 0, allLinSteps = 0;
333 number allLinRatesProduct = 1.0, allNonLinRatesProduct = 1.0;
334 for(
int call = 0; call < (int)m_vLinSolverCalls.size(); ++call)
336 UG_LOG(
" " << std::setw(10) << call+1 <<
" | ");
337 UG_LOG(std::setw(9) << m_vLinSolverCalls[call] <<
" | ");
338 allCalls += m_vLinSolverCalls[call];
339 UG_LOG(std::setw(15) << m_vTotalLinSolverSteps[call] <<
" | ");
340 allLinSteps += m_vTotalLinSolverSteps[call];
341 UG_LOG(std::setw(13) << std::setprecision(2) << std::fixed << m_vTotalLinSolverSteps[call] / (
double)m_vLinSolverCalls[call] <<
" | ");
342 allNonLinRatesProduct *= pow((
number)m_vNonLinSolverRates[call]/(
double)m_vLinSolverCalls[call],(
double)m_vLinSolverCalls[call]);
343 UG_LOG(std::setw(16) << std::setprecision(6) << std::scientific << m_vNonLinSolverRates[call] / (
double)m_vLinSolverCalls[call] <<
" | ");
344 allLinRatesProduct *= (
number)std::pow((
number)m_vLinSolverRates[call]/(double)m_vLinSolverCalls[call],(
number)m_vTotalLinSolverSteps[call]);
345 UG_LOG(std::setw(13) << std::setprecision(6) << std::scientific << m_vLinSolverRates[call] / (
double)m_vLinSolverCalls[call]);
349 UG_LOG(std::setw(9) << allCalls <<
" | ");
350 UG_LOG(std::setw(15) << allLinSteps <<
" | ");
351 UG_LOG(std::setw(13) << std::setprecision(2) << std::fixed << allLinSteps / (
number)allCalls <<
" | ");
352 UG_LOG(std::setw(16) << std::setprecision(6) << std::scientific << std::pow((
number)allNonLinRatesProduct,(
number)1.0/(
number)allCalls) <<
" | ");
353 UG_LOG(std::setw(13) << std::setprecision(6) << std::scientific << std::pow((
number)allLinRatesProduct,(
number)1.0/(
number)allLinSteps));
357 template <
typename TAlgebra>
360 return m_vLinSolverCalls.size();
363 template <
typename TAlgebra>
366 return m_vLinSolverCalls[call];
369 template <
typename TAlgebra>
372 return m_vTotalLinSolverSteps[call];
375 template <
typename TAlgebra>
378 return m_vTotalLinSolverSteps[call] / ((double)m_vLinSolverCalls[call]);
381 template <
typename TAlgebra>
385 for(
size_t call = 0; call < m_vLinSolverCalls.size(); ++call)
386 allCalls += m_vLinSolverCalls[call];
390 template <
typename TAlgebra>
394 for(
size_t call = 0; call < m_vLinSolverCalls.size(); ++call)
395 allSteps += m_vTotalLinSolverSteps[call];
399 template <
typename TAlgebra>
402 return total_linsolver_steps()/((double)total_linsolver_calls());
406 template <
typename TAlgebra>
409 m_vLinSolverRates.clear();
410 m_vNonLinSolverRates.clear();
411 m_vLinSolverCalls.clear();
412 m_vTotalLinSolverSteps.clear();
415 template <
typename TAlgebra>
419 char ext[20]; snprintf(ext, 20,
"_call%03d", m_dgbCall);
423 base_writer_type::write_debug(vec,
name + ext);
426 template <
typename TAlgebra>
430 char ext[20]; snprintf(ext, 20,
"_call%03d", m_dgbCall);
434 base_writer_type::write_debug(mat,
name + ext);
437 template <
typename TAlgebra>
440 std::stringstream ss;
441 ss <<
"NewtonSolver\n";
442 ss <<
" LinearSolver: ";
443 if(m_spLinearSolver.valid()) ss <<
ConfigShift(m_spLinearSolver->config_string()) <<
"\n";
444 else ss <<
" NOT SET!\n";
445 ss <<
" ConvergenceCheck: ";
446 if(m_spConvCheck.valid()) ss <<
ConfigShift(m_spConvCheck->config_string()) <<
"\n";
447 else ss <<
" NOT SET!\n";
448 ss <<
" LineSearch: ";
449 if(m_spLineSearch.valid()) ss <<
ConfigShift(m_spLineSearch->config_string()) <<
"\n";
450 else ss <<
" not set.\n";
451 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:60
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:382
void clear_average_convergence()
resets average linear solver convergence
Definition: newton_impl.h:407
virtual bool prepare(vector_type &u)
prepare Operator
Definition: newton_impl.h:142
virtual bool apply(vector_type &u)
apply Operator, i.e. N^{-1}(0) = u
Definition: newton_impl.h:149
NewtonSolver()
default constructor
Definition: newton_impl.h:74
virtual bool init(SmartPtr< IOperator< vector_type > > N)
This operator inverts the Operator N: Y -> X.
Definition: newton_impl.h:130
int num_linsolver_steps(size_t call) const
Definition: newton_impl.h:370
void write_debug(const vector_type &vec, std::string filename)
Definition: newton_impl.h:416
double total_average_linear_steps() const
Definition: newton_impl.h:400
virtual std::string config_string() const
returns information about configuration parameters
Definition: newton_impl.h:438
double average_linear_steps(size_t call) const
Definition: newton_impl.h:376
SmartPtr< AssembledOperator< algebra_type > > m_N
assembling routine
Definition: newton.h:173
void print_average_convergence() const
prints average linear solver convergence
Definition: newton_impl.h:328
size_t num_newton_steps() const
Definition: newton_impl.h:358
void set_convergence_check(SmartPtr< IConvergenceCheck< vector_type > > spConvCheck)
sets the convergence check
Definition: newton_impl.h:121
SmartPtr< IAssemble< TAlgebra > > m_spAss
assembling
Definition: newton.h:177
int num_linsolver_calls(size_t call) const
Definition: newton_impl.h:364
int total_linsolver_steps() const
Definition: newton_impl.h:391
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
string ConfigShift(string s)
Definition: string_util.cpp:457
#define NEWTON_PROFILE_END()
Definition: newton_impl.h:47
#define NEWTON_PROFILE_BEGIN(name)
Definition: newton_impl.h:46
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)