⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newtonsolver.cpp

📁 利用C
💻 CPP
字号:
// Copyright (C) 2005-2007 Garth N. Wells.// Licensed under the GNU LGPL Version 2.1.//// Modified by Anders Logg, 2005-2008.//// First added:  2005-10-23// Last changed: 2008-05-10#include "NewtonSolver.h"#include "NonlinearProblem.h"#include <dolfin/la/LUSolver.h>#include <dolfin/la/KrylovSolver.h>#include <iostream>using namespace dolfin;//-----------------------------------------------------------------------------NewtonSolver::NewtonSolver() : Parametrized(){  solver = new LinearSolver(lu);}//-----------------------------------------------------------------------------/*#ifdef HAS_PETSCNewtonSolver::NewtonSolver(Matrix::Type matrix_type) : Parametrized(){  solver = new LUSolver();  // FIXME: Need to select appropriate PETSc matrix  //A = new Matrix(matrix_type);  A = new Matrix;}#endif*///-----------------------------------------------------------------------------NewtonSolver::NewtonSolver(SolverType method, PreconditionerType pc)  : Parametrized(){  solver = new LinearSolver(method, pc);}//-----------------------------------------------------------------------------NewtonSolver::~NewtonSolver(){  delete solver; }//-----------------------------------------------------------------------------dolfin::uint NewtonSolver::solve(NonlinearProblem& nonlinear_problem, Vector& x){  const uint maxit= get("Newton maximum iterations");  // FIXME: add option to compute F(u) anf J together or separately  begin("Starting Newton solve.");  // Compute F(u) and J  set("output destination", "silent");  nonlinear_problem.form(A, b, x);  uint krylov_iterations = 0;  newton_iteration = 0;  bool newton_converged = false;  // Start iterations  while( !newton_converged && newton_iteration < maxit )  {      set("output destination", "silent");      // Perform linear solve and update total number of Krylov iterations      krylov_iterations += solver->solve(A, dx, b);      set("output destination", "terminal");      // Compute initial residual      if(newton_iteration == 0)        newton_converged = converged(b, dx, nonlinear_problem);      // Update solution      x += dx;      ++newton_iteration;      set("output destination", "silent");      //FIXME: this step is not needed if residual is based on dx and this has converged.      // Compute F(u) and J      nonlinear_problem.form(A, b, x);      set("output destination", "terminal");      // Test for convergence       newton_converged = converged(b, dx, nonlinear_problem);  }  if(newton_converged)    message("Newton solver finished in %d iterations and %d linear solver iterations.",         newton_iteration, krylov_iterations);  else    warning("Newton solver did not converge.");  end();  return newton_iteration;} //-----------------------------------------------------------------------------dolfin::uint NewtonSolver::getIteration() const{  return newton_iteration; }//-----------------------------------------------------------------------------bool NewtonSolver::converged(const Vector& b, const Vector& dx,       const NonlinearProblem& nonlinear_problem){  const std::string convergence_criterion = get("Newton convergence criterion");  const real rtol   = get("Newton relative tolerance");  const real atol   = get("Newton absolute tolerance");  const bool report = get("Newton report");  real residual = 1.0;  // Compute resdiual  if(convergence_criterion == "residual")    residual = b.norm();  else if (convergence_criterion == "incremental")    residual = dx.norm();  else    error("Unknown Newton convergence criterion");  // If this is the first iteration step, set initial residual  if(newton_iteration == 0)    residual0 = residual;  // Relative residual  real relative_residual = residual/residual0;  // Output iteration number and residual  //FIXME: allow precision to be set for dolfin::cout<<  std::cout.precision(3);  if(report && newton_iteration >0)     std::cout<< "  Iteration = " << newton_iteration  << ", Absolute, relative residual ("     << convergence_criterion  << " criterion) = " << std::scientific << residual     << ", "<< std::scientific << relative_residual << std::endl;  // Return true of convergence criterion is met  if(relative_residual < rtol || residual < atol)    return true;  // Otherwise return false  return false;}//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -