WaveBEM: Unsteady Nonlinear Potential Flow Solver for Ship-Wave Interaction.
newton_solver.h
Go to the documentation of this file.
1 #ifndef newton_solver_h
2 #define newton_solver_h
3 
7 
8 
9 #include "Epetra_ConfigDefs.h"
10 #ifdef HAVE_MPI
11 # include "mpi.h"
12 # include "Epetra_MpiComm.h"
13 #else
14 # include "Epetra_SerialComm.h"
15 #endif
16 
17 
18 
19 #include "Epetra_Map.h"
20 #include "Epetra_Vector.h"
21 #include "Epetra_RowMatrix.h"
22 #include "Epetra_CrsMatrix.h"
23 
24 #include "NOX.H"
25 #include "NOX_Epetra_Interface_Required.H"
26 #include "NOX_Epetra_Interface_Jacobian.H"
27 #include "NOX_Epetra_Interface_Preconditioner.H"
28 #include "NOX_Epetra_LinearSystem_AztecOO.H"
29 #include "NOX_Epetra_Group.H"
30 #include "newton_argument.h"
32 
33 
34 
35 
36 
37 
38 
39 // ==========================================================================
40 // JacobianOperator is the class that implements the user provided jacobian
41 // as an EpetraOperator
42 // ==========================================================================
44 
45  public Epetra_Operator
46 {
47 public:
48 
49  // The constructor accepts an initial guess and the ode_argument class
50  // containing the specific function to be zeroed. We make
51  // deep copies of each.
53  const Vector<double> &current_solution,
54  const Epetra_Map &Map,
55  const Epetra_Comm &Comm) :
56  solver(Solver),
57  y(current_solution),
58  comm(Comm),
59  map(Map)
60  {
61  }
62 
64  {
65  }
66 
67  int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
68  {
69 
70  Assert(X.Map().NumGlobalElements() == int(solver.n_dofs()),
71  ExcDimensionMismatch(X.Map().NumGlobalElements(), solver.n_dofs()));
72  Assert(Y.Map().NumGlobalElements() == int(solver.n_dofs()),
73  ExcDimensionMismatch(Y.Map().NumGlobalElements(), solver.n_dofs()));
74  const VectorView<double> x(X.Map().NumGlobalElements(), &X[0][0]);
75  VectorView<double> dst(Y.Map().NumGlobalElements(), &Y[0][0]);
76 
77  solver.jacobian(dst,y,x);
78  //cout<<"X: "<<X[0][0]<<" "<<X[0][1]<<" (t)"<<endl;
79  //cout<<"x: "<<x(0)<<" "<<x(1)<<" (d)"<<endl;
80  //cout<<"Y: "<<Y[0][0]<<" "<<Y[0][1]<<" (t)"<<endl;
81  //cout<<"dst: "<<dst(0)<<" "<<dst(1)<<" (d)"<<endl;
82  //cout<<"y: "<<y(0)<<" "<<y(1)<<" (d)"<<endl;
83  return 0;
84 
85  }
86 
87  void vmult(Vector<double> &dst, const Vector<double> &src) const
88  {
89 
90  Assert(dst.size() == solver.n_dofs(),
92  Assert(src.size() == solver.n_dofs(),
94 
95  solver.jacobian(dst,y,src);
96 
97  }
98 
99  int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
100  {
101  Assert(false, ExcPureFunctionCalled());
102  return 0;
103  }
104 
105 
106  double NormInf() const
107  {
108  Assert(false, ExcPureFunctionCalled());
109  return 0;
110  }
111 
113  {
114  UseTranspose = false;
115  return 0;
116  }
117 
118  const char *Label() const
119  {
120  return ("jacobian_operator");
121  }
122 
123  bool UseTranspose() const
124  {
125  return false;
126  }
127 
128  bool HasNormInf() const
129  {
130  return false;
131  }
132 
133  const Epetra_Comm &Comm() const
134  {
135  return comm;
136  }
137 
138  const Epetra_Map &OperatorDomainMap() const
139  {
140  return map;
141  }
142 
143  const Epetra_Map &OperatorRangeMap() const
144  {
145  return map;
146  }
147 
148 
149 
150 private:
153  const Epetra_Comm &comm;
154  const Epetra_Map &map;
155 
156 };
157 
158 
159 // ==========================================================================
160 // PreconditionerOperator is the class that implements the user provided jacobian
161 // as an EpetraOperator
162 // ==========================================================================
164 
165  public Epetra_Operator
166 {
167 public:
168 
169  // The constructor accepts an initial guess and the ode_argument class
170  // containing the specific function to be zeroed. We make
171  // deep copies of each.
173  const Vector<double> &current_solution,
174  const Epetra_Map &Map,
175  const Epetra_Comm &Comm) :
176  solver(Solver),
177  y(current_solution),
178  comm(Comm),
179  map(Map)
180  {
181  }
182 
184  {
185  }
186 
187  int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
188  {
189  Assert(X.Map().NumGlobalElements() == int(solver.n_dofs()),
190  ExcDimensionMismatch(X.Map().NumGlobalElements(), solver.n_dofs()));
191  Assert(Y.Map().NumGlobalElements() == int(solver.n_dofs()),
192  ExcDimensionMismatch(Y.Map().NumGlobalElements(), solver.n_dofs()));
193  const VectorView<double> x(X.Map().NumGlobalElements(), &X[0][0]);
194  VectorView<double> dst(Y.Map().NumGlobalElements(), &Y[0][0]);
195 
196  solver.jacobian_prec_prod(dst,y,x);
197 
198  return 0;
199 
200  }
201 
202 
203  int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
204  {
205  //cout<<"X: "<<X[0][0]<<" "<<X[0][1]<<" (t)"<<endl;
206  //cout<<"Y: "<<Y[0][0]<<" "<<Y[0][1]<<" (t)"<<endl;
207 
208  //Y[0][0] = 5.0;
209 
210  //cout<<"*X: "<<X[0][0]<<" "<<X[0][1]<<" (t)"<<endl;
211  //cout<<"*Y: "<<Y[0][0]<<" "<<Y[0][1]<<" (t)"<<endl;
212 
213  Assert(X.Map().NumGlobalElements() == int(solver.n_dofs()),
214  ExcDimensionMismatch(X.Map().NumGlobalElements(), solver.n_dofs()));
215  Assert(Y.Map().NumGlobalElements() == int(solver.n_dofs()),
216  ExcDimensionMismatch(Y.Map().NumGlobalElements(), solver.n_dofs()));
217  const VectorView<double> x(X.Map().NumGlobalElements(), &X[0][0]);
218  VectorView<double> dst(Y.Map().NumGlobalElements(), &Y[0][0]);
219 
220  solver.jacobian_prec(dst,y,x);
221 
222  //cout<<"X: "<<X[0][0]<<" "<<X[0][1]<<" (t)"<<endl;
223  //cout<<"x: "<<x(0)<<" "<<x(1)<<" (d)"<<endl;
224  //cout<<"Y: "<<Y[0][0]<<" "<<Y[0][1]<<" (t)"<<endl;
225  //cout<<"dst: "<<dst(0)<<" "<<dst(1)<<" (d)"<<endl;
226  //cout<<"y: "<<y(0)<<" "<<y(1)<<" (d)"<<endl;
227  return 0;
228  }
229 
230  void vmult(Vector<double> &dst, const Vector<double> &src) const
231  {
232 
233  Assert(dst.size() == solver.n_dofs(),
235  Assert(src.size() == solver.n_dofs(),
237 
238  solver.jacobian_prec(dst,y,src);
239 
240  }
241 
242 
243  double NormInf() const
244  {
245  Assert(false, ExcPureFunctionCalled());
246  return 0;
247  }
248 
250  {
251  UseTranspose = false;
252  return 0;
253  }
254 
255  const char *Label() const
256  {
257  return ("preconditioner_operator");
258  }
259 
260  bool UseTranspose() const
261  {
262  return false;
263  }
264 
265  bool HasNormInf() const
266  {
267  return false;
268  }
269 
270  const Epetra_Comm &Comm() const
271  {
272  return comm;
273  }
274 
275  const Epetra_Map &OperatorDomainMap() const
276  {
277  return map;
278  }
279 
280  const Epetra_Map &OperatorRangeMap() const
281  {
282  return map;
283  }
284 
285 
286 
287 private:
290  const Epetra_Comm &comm;
291  const Epetra_Map &map;
292 
293 
294 };
295 
296 
297 
298 // ==========================================================================
299 // ProblemInterface, the problem interface in this example,
300 // defines the interface between NOX and our nonlinear problem to
301 // solve.
302 // ==========================================================================
304  public NOX::Epetra::Interface::Required,
305  public NOX::Epetra::Interface::Jacobian,
306  public NOX::Epetra::Interface::Preconditioner
307 {
308 public:
309 
310  // The constructor accepts an initial guess and the ode_argument class
311  // containing the specific function to be zeroed. We make
312  // deep copies of each.
314  Vector<double> &current_sol,
315  PreconditionerOperator &prec_oper,
316  JacobianOperator &jac_oper) :
317  solver(Solver),
318  y(current_sol),
319  preconditioner_operator(prec_oper),
320  jacobian_operator(jac_oper)
321  {
322 
323  }
324 
326  {
327  }
328 
329  // Compute f := F(x), where x is the input vector and f the output
330  // vector.
331  bool
332  computeF (const Epetra_Vector &x,
333  Epetra_Vector &f,
334  NOX::Epetra::Interface::Required::FillType F)
335  {
336 
337  Assert(x.Map().NumGlobalElements() == int(solver.n_dofs()),
338  ExcDimensionMismatch(x.Map().NumGlobalElements(), solver.n_dofs()));
339  Assert(f.Map().NumGlobalElements() == int(solver.n_dofs()),
340  ExcDimensionMismatch(f.Map().NumGlobalElements(), solver.n_dofs()));
341 
342 
343  const VectorView<double> yy(x.Map().NumGlobalElements(), &x[0]);
344  VectorView<double> residual(f.Map().NumGlobalElements(), &f[0]);
345 
346  solver.residual(residual, yy);
347 
348  return true;
349  };
350 
351  bool
352  computeJacobian(const Epetra_Vector &x, Epetra_Operator &Jac)
353  {
354 
355  Assert(x.Map().NumGlobalElements() == int(solver.n_dofs()),
356  ExcDimensionMismatch(x.Map().NumGlobalElements(), solver.n_dofs()));
357 
358  const VectorView<double> yy(x.Map().NumGlobalElements(), &x[0]);
359  y = yy;
360  Jac = jacobian_operator;
361  //Epetra_Vector y(x);
362  //cout<<"Test "<<endl,
363  //Jac.Apply(x,y);
364 
365  return true;
366  }
367 
368 
369 
370  bool computePrecMatrix (const Epetra_Vector &x,
371  Epetra_RowMatrix &M)
372  {
373  throw std::runtime_error ("*** ProblemInterface does not implement "
374  "computing an explicit preconditioner from an "
375  "Epetra_RowMatrix ***");
376  }
377 
378  bool computePreconditioner (const Epetra_Vector &x,
379  Epetra_Operator &Prec,
380  Teuchos::ParameterList * =0)
381  {
382  Assert(x.Map().NumGlobalElements() == int(solver.n_dofs()),
383  ExcDimensionMismatch(x.Map().NumGlobalElements(), solver.n_dofs()));
384 
385  const VectorView<double> yy(x.Map().NumGlobalElements(), &x[0]);
387  y = yy;
389 
390  return true;
391  }
392 
393 
394 
395 private:
396 
401 
402 };
403 
405 {
406 public:
412 
413 
415  ~NewtonSolver();
416 
418  static void declare_parameters(ParameterHandler &prm);
419 
422 
424  unsigned int solve(Vector<double> &solution,
425  const unsigned int max_steps);
426 
427 
428 
429 
430 private:
434 #ifdef EPETRA_MPI
435  Epetra_MpiComm comm;
436 #else
437  Epetra_SerialComm comm;
438 #endif
439  Epetra_Map map;
442  std::string linear_solver_name;
445  double rel_tol;
448 
449 
450 };
451 
452 #endif
static::ExceptionBase & ExcPureFunctionCalled()
virtual int jacobian_prec(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Inverse Jacobian preconditioner vector product.
bool computePrecMatrix(const Epetra_Vector &x, Epetra_RowMatrix &M)
const char * Label() const
void parse_parameters(ParameterHandler &prm)
Parse a parameter handler.
virtual ~ProblemInterface()
const Epetra_Map & OperatorRangeMap() const
void vmult(Vector< double > &dst, const Vector< double > &src) const
NewtonArgument & solver
const Epetra_Map & map
const Epetra_Map & OperatorDomainMap() const
virtual unsigned int n_dofs() const =0
Returns the number of degrees of freedom.
PreconditionerOperator & preconditioner_operator
const Epetra_Map & OperatorRangeMap() const
const Vector< double > & y
bool provide_jac_prec
int SetUseTranspose(bool UseTranspose)
Vector< double > & y
virtual int jacobian(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Jacobian vector product.
NewtonArgument & solver
The bubble membrane poperties.
bool HasNormInf() const
virtual int setup_jacobian_prec(const Vector< double > &src_yy)
Setup Jacobian preconditioner (builds the Jacobian preconditioner matrix).
NewtonArgument & solver
void vmult(Vector< double > &dst, const Vector< double > &src) const
Definition: newton_solver.h:87
bool HasNormInf() const
const Epetra_Map & map
PreconditionerOperator(NewtonArgument &Solver, const Vector< double > &current_solution, const Epetra_Map &Map, const Epetra_Comm &Comm)
NewtonSolver(NewtonArgument &solver)
Constructor for the NewtonSolver class.
std::string linear_solver_name
Epetra_SerialComm comm
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
bool computePreconditioner(const Epetra_Vector &x, Epetra_Operator &Prec, Teuchos::ParameterList *=0)
Vector< double > y
const Vector< double > & y
#define Assert(cond, exc)
int SetUseTranspose(bool UseTranspose)
virtual int jacobian_prec_prod(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Jacobian preconditioner vector product.
static::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
SolverControl solver_control
double NormInf() const
int Apply(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Definition: newton_solver.h:67
bool computeF(const Epetra_Vector &x, Epetra_Vector &f, NOX::Epetra::Interface::Required::FillType F)
int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Epetra_Map map
std::size_t size() const
const Epetra_Comm & Comm() const
virtual int residual(Vector< double > &dst, const Vector< double > &src_yy)=0
For dae problems, we need a residual function.
double linear_rel_tol
JacobianOperator(NewtonArgument &Solver, const Vector< double > &current_solution, const Epetra_Map &Map, const Epetra_Comm &Comm)
Definition: newton_solver.h:52
const Epetra_Comm & comm
const Epetra_Comm & Comm() const
const Epetra_Comm & comm
const char * Label() const
Base class that needs to be inherited by any function that wants to use the newton solver class...
unsigned int solve(Vector< double > &solution, const unsigned int max_steps)
Solve.
PreconditionerOperator * preconditioner_operator
JacobianOperator & jacobian_operator
bool UseTranspose() const
static void declare_parameters(ParameterHandler &prm)
Declare parameters for this class to function properly.
int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const
Definition: newton_solver.h:99
virtual ~JacobianOperator()
Definition: newton_solver.h:63
NewtonArgument & solver
~NewtonSolver()
House cleaning.
const Epetra_Map & OperatorDomainMap() const
virtual ~PreconditionerOperator()
JacobianOperator * jacobian_operator
ProblemInterface(NewtonArgument &Solver, Vector< double > &current_sol, PreconditionerOperator &prec_oper, JacobianOperator &jac_oper)
bool computeJacobian(const Epetra_Vector &x, Epetra_Operator &Jac)
bool UseTranspose() const
double NormInf() const