Amandus: Simulations based on multilevel Schwarz methods
constrained_newton.h
Go to the documentation of this file.
1 /**********************************************************************
2  * Copyright (C) 2011 - 2014 by the authors
3  * Distributed under the MIT License
4  *
5  * See the files AUTHORS and LICENSE in the project root directory
6  **********************************************************************/
7 #ifndef __darcy_checkerboard_constrained_newton_h
8 #define __darcy_checkerboard_constrained_newton_h
9 
10 #include <deal.II/algorithms/newton.h>
11 
12 #include <deal.II/base/logstream.h>
13 #include <deal.II/lac/vector_memory.h>
14 
15 namespace Darcy
16 {
17 namespace Checkerboard
18 {
19 using namespace dealii;
20 using namespace Algorithms;
21 
29 template <class VECTOR>
30 class ConstrainedNewton : public Newton<VECTOR>
31 {
32 public:
33  ConstrainedNewton(OperatorBase& residual, OperatorBase& inverse_derivative);
34  virtual void operator()(AnyData& out, const AnyData& in);
35 
36  bool constraint_violation(const VECTOR& u);
37 
38 private:
39  SmartPointer<OperatorBase, Newton<VECTOR>> residual;
40 
41  SmartPointer<OperatorBase, Newton<VECTOR>> inverse_derivative;
42 
43  const unsigned int n_stepsize_iterations;
44 };
45 
46 template <class VECTOR>
48  OperatorBase& inverse_derivative)
49  : Newton<VECTOR>(residual, inverse_derivative)
50  , residual(&residual)
51  , inverse_derivative(&inverse_derivative)
52  , n_stepsize_iterations(21)
53 {
54 }
55 
56 template <class VECTOR>
57 void
58 ConstrainedNewton<VECTOR>::operator()(AnyData& out, const AnyData& in)
59 {
60  Assert(out.size() == 1, ExcNotImplemented());
61  deallog.push("Newton");
62 
63  VECTOR& u = *out.entry<VECTOR*>(0);
64 
65  GrowingVectorMemory<VECTOR> mem;
66  typename VectorMemory<VECTOR>::Pointer Du(mem);
67  typename VectorMemory<VECTOR>::Pointer res(mem);
68 
69  res->reinit(u);
70  AnyData src1;
71  AnyData src2;
72  src1.add<const VECTOR*>(&u, "Newton iterate");
73  src1.merge(in);
74  src2.add<const VECTOR*>(res, "Newton residual");
75  src2.merge(src1);
76  AnyData out1;
77  out1.add<VECTOR*>(res, "Residual");
78  AnyData out2;
79  out2.add<VECTOR*>(Du, "Update");
80 
81  unsigned int step = 0;
82  // fill res with (f(u), v)
83  (*residual)(out1, src1);
84  double resnorm = res->l2_norm();
85  double old_residual;
86 
87  while (this->control.check(step++, resnorm) == SolverControl::iterate)
88  {
89  Du->reinit(u);
90  try
91  {
92  (*inverse_derivative)(out2, src2);
93  }
94  catch (SolverControl::NoConvergence& e)
95  {
96  deallog << "Inner iteration failed after " << e.last_step << " steps with residual "
97  << e.last_residual << std::endl;
98  }
99 
100  u.add(-1., *Du);
101  old_residual = resnorm;
102  (*residual)(out1, src1);
103  resnorm = res->l2_norm();
104 
105  // Step size control
106  unsigned int step_size = 0;
107  while (resnorm >= old_residual || constraint_violation(u))
108  {
109  ++step_size;
110  if (step_size > n_stepsize_iterations)
111  {
112  deallog << "No smaller stepsize allowed!";
113  break;
114  }
115  if (this->control.log_history())
116  deallog << "Trying step size: 1/" << (1 << step_size) << " since residual was " << resnorm
117  << std::endl;
118  u.add(1. / (1 << step_size), *Du);
119  (*residual)(out1, src1);
120  resnorm = res->l2_norm();
121  }
122  }
123  deallog.pop();
124 
125  // in case of failure: throw exception
126  if (this->control.last_check() != SolverControl::success)
127  AssertThrow(
128  false, SolverControl::NoConvergence(this->control.last_step(), this->control.last_value()));
129  // otherwise exit as normal
130 }
131 
132 template <class VECTOR>
133 bool
135 {
136  double gamma = u[0];
137  double sigma = u[1];
138  double rho = u[2];
139  if (!(0.0 < gamma && gamma < 2))
140  {
141  return true;
142  }
143  if (!(std::max(0.0, numbers::PI * gamma - numbers::PI) < 2 * rho * gamma &&
144  2 * rho * gamma < std::min(numbers::PI * gamma, numbers::PI)))
145  {
146  return true;
147  }
148  if (!(std::max(0.0, numbers::PI - numbers::PI * gamma) < -2 * sigma * gamma &&
149  -2 * sigma * gamma < std::min(numbers::PI, 2 * numbers::PI - numbers::PI * gamma)))
150  {
151  return true;
152  }
153  return false;
154 }
155 }
156 }
157 
158 #endif
bool constraint_violation(const VECTOR &u)
Definition: constrained_newton.h:134
virtual void operator()(AnyData &out, const AnyData &in)
Definition: constrained_newton.h:58
SmartPointer< OperatorBase, Newton< VECTOR > > inverse_derivative
Definition: constrained_newton.h:41
const unsigned int n_stepsize_iterations
Definition: constrained_newton.h:43
Definition: constrained_newton.h:30
Definition: constrained_newton.h:15
ConstrainedNewton(OperatorBase &residual, OperatorBase &inverse_derivative)
Definition: constrained_newton.h:47
SmartPointer< OperatorBase, Newton< VECTOR > > residual
Definition: constrained_newton.h:39