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();
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));