GetFEM++  5.3
getfem_model_solvers.cc
1 /*===========================================================================
2 
3  Copyright (C) 2009-2017 Yves Renard
4 
5  This file is a part of GetFEM++
6 
7  GetFEM++ is free software; you can redistribute it and/or modify it
8  under the terms of the GNU Lesser General Public License as published
9  by the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version along with the GCC Runtime Library
11  Exception either version 3.1 or (at your option) any later version.
12  This program is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15  License and GCC Runtime Library Exception for more details.
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program; if not, write to the Free Software Foundation,
18  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20 ===========================================================================*/
21 
23 #include "gmm/gmm_inoutput.h"
24 #include <iomanip>
25 
26 namespace getfem {
27 
28 
29  static rmodel_plsolver_type rdefault_linear_solver(const model &md) {
30  return default_linear_solver<model_real_sparse_matrix,
31  model_real_plain_vector>(md);
32  }
33 
34  static cmodel_plsolver_type cdefault_linear_solver(const model &md) {
35  return default_linear_solver<model_complex_sparse_matrix,
36  model_complex_plain_vector>(md);
37  }
38 
39  void default_newton_line_search::init_search(double r, size_t git, double) {
40  alpha_min_ratio = 0.9;
41  alpha_min = 1e-10;
42  alpha_max_ratio = 10.0;
43  alpha_mult = 0.25;
44  itmax = size_type(-1);
45  glob_it = git; if (git <= 1) count_pat = 0;
46  conv_alpha = alpha = alpha_old = 1.;
47  conv_r = first_res = r; it = 0;
48  count = 0;
49  max_ratio_reached = false;
50  }
51 
52  double default_newton_line_search::next_try(void) {
53  alpha_old = alpha; ++it;
54  // alpha *= 0.5;
55  if (alpha >= 0.4) alpha *= 0.5; else alpha *= alpha_mult;
56  return alpha_old;
57  }
58 
59  bool default_newton_line_search::is_converged(double r, double) {
60  // cout << "r = " << r << " alpha = " << alpha_old << " count_pat = " << count_pat << endl;
61  if (!max_ratio_reached && r < first_res * alpha_max_ratio) {
62  alpha_max_ratio_reached = alpha_old; r_max_ratio_reached = r;
63  it_max_ratio_reached = it; max_ratio_reached = true;
64  }
65  if (max_ratio_reached &&
66  r < r_max_ratio_reached * 0.5 &&
67  r > first_res * 1.1 && it <= it_max_ratio_reached+1) {
68  alpha_max_ratio_reached = alpha_old; r_max_ratio_reached = r;
69  it_max_ratio_reached = it;
70  }
71  if (count == 0 || r < conv_r)
72  { conv_r = r; conv_alpha = alpha_old; count = 1; }
73  if (conv_r < first_res) ++count;
74 
75  if (r < first_res * alpha_min_ratio)
76  { count_pat = 0; return true; }
77  if (count>=5 || (alpha < alpha_min && max_ratio_reached) || alpha<1e-15) {
78  if (conv_r < first_res * 0.99) count_pat = 0;
79  if (/*gmm::random() * 50. < -log(conv_alpha)-4.0 ||*/ count_pat >= 3)
80  { conv_r=r_max_ratio_reached; conv_alpha=alpha_max_ratio_reached; }
81  if (conv_r >= first_res * 0.999) count_pat++;
82  return true;
83  }
84  return false;
85  }
86 
87 
88  /* ***************************************************************** */
89  /* Computation of initial values of velocity/acceleration for */
90  /* time integration schemes. */
91  /* ***************************************************************** */
92 
93  template <typename MATRIX, typename VECTOR, typename PLSOLVER>
94  void compute_init_values(model &md, gmm::iteration &iter,
95  PLSOLVER lsolver,
96  abstract_newton_line_search &ls, const MATRIX &K,
97  const VECTOR &rhs) {
98 
99  VECTOR state(md.nb_dof());
100  md.from_variables(state);
101  md.cancel_init_step();
102  md.set_time_integration(2);
103  scalar_type dt = md.get_time_step();
104  scalar_type ddt = md.get_init_time_step();
105  scalar_type t = md.get_time();
106 
107  // Solve for ddt
108  md.set_time_step(ddt);
109  gmm::iteration iter1 = iter;
110  standard_solve(md, iter1, lsolver, ls, K, rhs);
111  md.copy_init_time_derivative();
112 
113  // Restore the model state
114  md.set_time_step(dt);
115  md.set_time(t);
116  md.to_variables(state);
117  md.set_time_integration(1);
118  }
119 
120 
121  /* ***************************************************************** */
122  /* Standard solve. */
123  /* ***************************************************************** */
124 
125  template <typename MATRIX, typename VECTOR, typename PLSOLVER>
126  void standard_solve(model &md, gmm::iteration &iter,
127  PLSOLVER lsolver,
128  abstract_newton_line_search &ls, const MATRIX &K,
129  const VECTOR &rhs) {
130 
131  VECTOR state(md.nb_dof());
132  md.from_variables(state); // copy the model variables in the state vector
133 
134  int time_integration = md.is_time_integration();
135  if (time_integration) {
136  if (time_integration == 1 && md.is_init_step()) {
137  compute_init_values(md, iter, lsolver, ls, K, rhs);
138  return;
139  }
140  md.set_time(md.get_time() + md.get_time_step());
141  md.call_init_affine_dependent_variables(time_integration);
142  }
143 
144  if (md.is_linear()) {
145  md.assembly(model::BUILD_ALL);
146  (*lsolver)(K, state, rhs, iter);
147  }
148  else {
149  model_pb<MATRIX, VECTOR> mdpb(md, ls, state, rhs, K);
150  if (dynamic_cast<newton_search_with_step_control *>(&ls))
151  Newton_with_step_control(mdpb, iter, *lsolver);
152  else
153  classical_Newton(mdpb, iter, *lsolver);
154  }
155  md.to_variables(state); // copy the state vector into the model variables
156  }
157 
159  rmodel_plsolver_type lsolver,
160  abstract_newton_line_search &ls) {
161  standard_solve(md, iter, lsolver, ls, md.real_tangent_matrix(),
162  md.real_rhs());
163  }
164 
165  void standard_solve(model &md, gmm::iteration &iter,
166  cmodel_plsolver_type lsolver,
167  abstract_newton_line_search &ls) {
168  standard_solve(md, iter, lsolver, ls, md.complex_tangent_matrix(),
169  md.complex_rhs());
170  }
171 
172 
173  void standard_solve(model &md, gmm::iteration &iter,
174  rmodel_plsolver_type lsolver) {
175  default_newton_line_search ls;
176  standard_solve(md, iter, lsolver, ls);
177  }
178 
179  void standard_solve(model &md, gmm::iteration &iter,
180  cmodel_plsolver_type lsolver) {
181  newton_search_with_step_control ls;
182  // default_newton_line_search ls;
183  standard_solve(md, iter, lsolver, ls);
184  }
185 
186  void standard_solve(model &md, gmm::iteration &iter) {
187  newton_search_with_step_control ls;
188  // default_newton_line_search ls;
189  if (md.is_complex())
190  standard_solve(md, iter, cdefault_linear_solver(md), ls);
191  else
192  standard_solve(md, iter, rdefault_linear_solver(md), ls);
193  }
194 
195 
196 
197 } /* end of namespace getfem. */
198 
const model_real_plain_vector & real_rhs() const
Gives the access to the right hand side of the tangent linear system.
const model_complex_plain_vector & complex_rhs() const
Gives access to the right hand side of the tangent linear system.
The Iteration object calculates whether the solution has reached the desired accuracy, or whether the maximum number of iterations has been reached.
Definition: gmm_iter.h:53
void standard_solve(model &md, gmm::iteration &iter, rmodel_plsolver_type lsolver, abstract_newton_line_search &ls)
A default solver for the model brick system.
``Model&#39;&#39; variables store the variables, the data and the description of a model. ...
size_t size_type
used as the common size type in the library
Definition: bgeot_poly.h:49
Input/output on sparse matrices.
Standard solvers for model bricks.
bool is_complex() const
Boolean which says if the model deals with real or complex unknowns and data.
GEneric Tool for Finite Element Methods.
const model_real_sparse_matrix & real_tangent_matrix() const
Gives the access to the tangent matrix.
size_type alpha(short_type n, short_type d)
Return the value of which is the number of monomials of a polynomial of variables and degree ...
Definition: bgeot_poly.cc:46
const model_complex_sparse_matrix & complex_tangent_matrix() const
Gives the access to the tangent matrix.