MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
nonlinear_solver.hpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2020 Manav Bhatia and MAST authors
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #ifndef __mast_petsc_nonlinear_solver_h__
21 #define __mast_petsc_nonlinear_solver_h__
22 
23 // C++ includes
24 #include <iomanip>
25 
26 // MAST includes
28 #include <mast/base/exceptions.hpp>
30 
31 // PETSc includes
32 #include <petscmat.h>
33 
34 
35 namespace MAST {
36 namespace Solvers {
37 namespace PETScWrapper {
38 
39 template <typename FuncType>
41 
42 public:
43 
47 
48  NonlinearSolver(const MPI_Comm comm):
49  tol (1.e-6),
50  rtol (1.e-6),
51  max_iter (20),
52  _comm (comm),
53  _func (nullptr) {
54 
55  }
56 
57 
58  virtual ~NonlinearSolver() {
59 
60  }
61 
68  inline void solve(FuncType &func,
69  Vec x,
70  const std::string *scope = nullptr) {
71 
72 
73  Vec res, x0, dx;
74  Mat *jac;
75 
76  VecDuplicate(x, &res);
77  VecDuplicate(x, &x0);
78  VecDuplicate(x, &dx);
79 
80  VecZeroEntries(res);
81 
82  func.residual(x, res);
83  jac = func.matrix();
84 
85  bool
86  if_cont = true;
87 
88  real_t
89  res_l2 = 0.,
90  res0_l2 = 0.,
91  dx_l2 = 0.;
92 
93  uint_t
94  iter = 0;
95 
96  VecNorm(res, NORM_2, &res_l2);
97  res0_l2 = res_l2;
98 
99  std::cout
100  << " Iter: " << std::setw(5) << iter
101  << " : || res ||_2 = "
102  << std::setw(15) << res_l2;
103 
104  while (if_cont) {
105 
106  func.jacobian(x, *jac);
107 
109  solver.init(*jac, _nm.size()?&_nm:nullptr);
110  solver.solve(dx, res);
111 
112  VecNorm(dx, NORM_2, &dx_l2);
113 
114  // output
115  std::cout
116  << " : || dx ||_2 = "
117  << std::setw(15) << dx_l2 << std::endl;
118 
119  // x = x + dx
120  VecAXPY(x, -1., dx);
121 
122  // copy solution to another vector
123  VecCopy(x, x0);
124  iter++;
125 
126  // new residual
127  func.residual(x, res);
128 
129  // check for convergence
130  VecNorm(res, NORM_2, &res_l2);
131 
132  std::cout
133  << " Iter: " << std::setw(5) << iter
134  << " : || res ||_2 = "
135  << std::setw(15) << res_l2;
136 
137  if (res_l2/res0_l2 < rtol) {
138 
139  if_cont = false;
140  std::cout
141  << " Terminating due to residual norm relative convergence"
142  << std::endl;
143  }
144  if (res_l2 < tol) {
145 
146  if_cont = false;
147  std::cout
148  << " Terminating due to residual norm convergence"
149  << std::endl;
150  }
151  if (dx_l2 < tol) {
152 
153  if_cont = false;
154  std::cout
155  << " Terminating due to step norm convergence"
156  << std::endl;
157  }
158  if (iter >= max_iter) {
159 
160  if_cont = false;
161  std::cout
162  << " Terminating due to maximum iterations"
163  << std::endl;
164  }
165  }
166  }
167 
168 
169 private:
170 
171  const MPI_Comm _comm;
172  FuncType *_func;
173  std::string _nm;
174 };
175 
176 } // PETScWrapper
177 } // Solvers
178 } // MAST
179 
180 #endif // __mast_petsc_nonlinear_solver_h__
void solve(FuncType &func, Vec x, const std::string *scope=nullptr)
initialize the solver for function object func that provides the residual and jacobian evaluation...
void solve(Vec x, Vec b)
Solves , where is the system matrix.
unsigned int uint_t
void init(Mat A, const std::string *scope=nullptr)
initialize the solver for operator matrix A.
double real_t