unsteady_solver.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 #include "libmesh/diff_solver.h"
20 #include "libmesh/diff_system.h"
21 #include "libmesh/dof_map.h"
22 #include "libmesh/numeric_vector.h"
24 
25 namespace libMesh
26 {
27 
28 
29 
31  : TimeSolver(s),
32  old_local_nonlinear_solution (NumericVector<Number>::build(s.comm())),
33  first_solve (true),
34  first_adjoint_step (true)
35 {
36 }
37 
38 
39 
41 {
42 }
43 
44 
45 
47 {
49 
50  _system.add_vector("_old_nonlinear_solution");
51 }
52 
53 
54 
56 {
57 #ifdef LIBMESH_ENABLE_GHOSTED
60  GHOSTED);
61 #else
63 #endif
64 }
65 
66 
67 
69 {
71 
72 #ifdef LIBMESH_ENABLE_GHOSTED
75  GHOSTED);
76 #else
78 #endif
79 
80  // localize the old solution
81  NumericVector<Number> &old_nonlinear_soln =
82  _system.get_vector("_old_nonlinear_solution");
83 
84  old_nonlinear_soln.localize
87 }
88 
89 
90 
92 {
93  if (first_solve)
94  {
96  first_solve = false;
97  }
98 
99  unsigned int solve_result = _diff_solver->solve();
100 
101  // If we requested the UnsteadySolver to attempt reducing dt after a
102  // failed DiffSolver solve, check the results of the solve now.
104  {
105  bool backtracking_failed =
107 
108  bool max_iterations =
110 
111  if (backtracking_failed || max_iterations)
112  {
113  // Cut timestep in half
114  for (unsigned int nr=0; nr<reduce_deltat_on_diffsolver_failure; ++nr)
115  {
116  _system.deltat *= 0.5;
117  libMesh::out << "Newton backtracking failed. Trying with smaller timestep, dt="
118  << _system.deltat << std::endl;
119 
120  solve_result = _diff_solver->solve();
121 
122  // Check solve results with reduced timestep
123  bool backtracking_still_failed =
125 
126  bool backtracking_max_iterations =
128 
129  if (!backtracking_still_failed && !backtracking_max_iterations)
130  {
131  if (!quiet)
132  libMesh::out << "Reduced dt solve succeeded." << std::endl;
133  return;
134  }
135  }
136 
137  // If we made it here, we still couldn't converge the solve after
138  // reducing deltat
139  libMesh::out << "DiffSolver::solve() did not succeed after "
140  << reduce_deltat_on_diffsolver_failure
141  << " attempts." << std::endl;
142  libmesh_convergence_failure();
143 
144  } // end if (backtracking_failed || max_iterations)
145  } // end if (reduce_deltat_on_diffsolver_failure)
146 }
147 
148 
149 
151 {
152  if (!first_solve)
153  {
154  // Store the solution, does nothing by default
155  // User has to attach appropriate solution_history object for this to
156  // actually store anything anywhere
157  solution_history->store();
158 
160  }
161 
162  NumericVector<Number> &old_nonlinear_soln =
163  _system.get_vector("_old_nonlinear_solution");
164  NumericVector<Number> &nonlinear_solution =
165  *(_system.solution);
166 
167  old_nonlinear_soln = nonlinear_solution;
168 
169  old_nonlinear_soln.localize
172 }
173 
174 
175 
177 {
178  // On the first call of this function, we dont save the adjoint solution or
179  // decrement the time, we just call the retrieve function below
180  if(!first_adjoint_step)
181  {
182  // Call the store function to store the last adjoint before decrementing the time
183  solution_history->store();
184  // Decrement the system time
186  }
187  else
188  {
189  first_adjoint_step = false;
190  }
191 
192  // Retrieve the primal solution vectors at this time using the
193  // solution_history object
194  solution_history->retrieve();
195 
196  // Dont forget to localize the old_nonlinear_solution !
197  _system.get_vector("_old_nonlinear_solution").localize
200 }
201 
203  {
204  // Retrieve all the stored vectors at the current time
205  solution_history->retrieve();
206 
207  // Dont forget to localize the old_nonlinear_solution !
208  _system.get_vector("_old_nonlinear_solution").localize
211  }
212 
213 
215 const
216 {
217  libmesh_assert_less (global_dof_number, _system.get_dof_map().n_dofs());
218  libmesh_assert_less (global_dof_number, old_local_nonlinear_solution->size());
219 
220  return (*old_local_nonlinear_solution)(global_dof_number);
221 }
222 
223 
224 
226 {
227 
228  AutoPtr<NumericVector<Number> > solution_copy =
229  _system.solution->clone();
230 
231  solution_copy->add(-1., _system.get_vector("_old_nonlinear_solution"));
232 
233  solution_copy->close();
234 
235  return _system.calculate_norm(*solution_copy, norm);
236 }
237 
238 } // namespace libMesh

Site Created By: libMesh Developers
Last modified: February 07 2014 16:57:07 UTC

Hosted By:
SourceForge.net Logo