dune-fem  2.4.1-rc
automaticdifferenceoperator.hh
Go to the documentation of this file.
1 // vim: set expandtab ts=2 sw=2 sts=2:
2 #ifndef DUNE_FEM_AUTOMATICDIFFERENCEOPERATOR_HH
3 #define DUNE_FEM_AUTOMATICDIFFERENCEOPERATOR_HH
4 
5 #include <limits>
6 
7 #include <dune/common/nullptr.hh>
8 
11 
12 namespace Dune
13 {
14 
15  namespace Fem
16  {
17 
18  // Internal Forward Declarations
19  // -----------------------------
20 
21  template< class DomainFunction, class RangeFunction, class LinearOperator >
23 
24 
25 
26  // AutomaticDifferenceLinearOperator
27  // ---------------------------------
28 
29  template< class DomainFunction, class RangeFunction = DomainFunction >
31  : public Dune::Fem::Operator< DomainFunction, RangeFunction >
32  {
35 
36  friend class AutomaticDifferenceOperator< DomainFunction, RangeFunction, ThisType >;
37 
38  public:
40 
45  typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
46 
47  typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType;
48  typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType;
49 
50  AutomaticDifferenceLinearOperator ( const std::string &name, const DomainSpaceType &dSpace, const RangeSpaceType &rSpace )
51  : name_( name ),
52  op_( 0 ), // initial value for op_ is 'undefined'
53  u_( 0 ), // initial value for u_ is 'undefined'
54  b_( "AutomaticDifferenceOperator::b_", dSpace ),
55  op_u_( "AutomaticDifferenceOperator::op_u_", rSpace ),
56  norm_u_( 0 )
57  {}
58 
59  virtual void operator() ( const DomainFunctionType &arg, RangeFunctionType &dest ) const;
60 
61  protected:
62  void set ( const DomainFunctionType &u, const OperatorType &op, const RealType &eps );
63  const std::string name_;
64  const OperatorType *op_;
65  const DomainFunctionType *u_;
66 
67  mutable DomainFunctionType b_;
68  RangeFunctionType op_u_;
69 
70  RangeFieldType eps_;
71  RangeFieldType norm_u_;
72  };
73 
74 
75 
76  // AutomaticDifferenceOperator
77  // ---------------------------
78 
85  template< class DomainFunction, class RangeFunction = DomainFunction,
88  : public Dune::Fem::DifferentiableOperator< LinearOperator >
89  {
91 
92  public:
97  typedef typename Dune::FieldTraits< RangeFieldType >::real_type RealType;
98 
100 
101  typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType;
102  typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType;
103 
105  : eps_( parameter.getValue< RangeFieldType >( "fem.differenceoperator.eps", RangeFieldType( 0 ) ) )
106  {}
107 
108  explicit AutomaticDifferenceOperator ( const RangeFieldType &eps )
109  : eps_( eps )
110  {}
111 
112  virtual void jacobian ( const DomainFunctionType &u, JacobianOperatorType &jOp ) const
113  {
114  jOp.set( u, *this, eps_ );
115  }
116 
117  private:
118  const RealType eps_;
119  };
120 
121 
122 
123  // Implementation of AutomaticDifferenceLinearOperator
124  // ---------------------------------------------------
125 
126  template< class DomainFunction, class RangeFunction >
128  ::operator() ( const DomainFunctionType &arg, RangeFunctionType &dest ) const
129  {
130  assert( op_ && u_ );
131 
132  // 'Normal' difference-quotient, i.e.
133  // dest = 1/eps (op_(*u +eps*arg) - op_(*u))
134  //
135  // eps is chosen dynamically, the same way as in
136  // dune-fem/dune/fem/solver/ode/quasi_exact_newton.cpp, see also
137  // http://www.freidok.uni-freiburg.de/volltexte/3762/pdf/diss.pdf, page 137
138  RealType eps = eps_;
139  if( eps <= RealType( 0. ) )
140  {
141  const RealType machine_eps = std::numeric_limits< RealType >::epsilon();
142  const RealType norm_p_sq = arg.normSquaredDofs( );
143  if( norm_p_sq > machine_eps )
144  eps = std::sqrt( (RealType( 1 ) + norm_u_) * machine_eps / norm_p_sq );
145  else
146  eps = std::sqrt( machine_eps );
147  }
148 
149  b_.assign( *u_ );
150  b_.axpy( eps, arg );
151  (*op_)( b_, dest );
152  dest -= op_u_;
153  dest *= RealType( 1 ) / eps;
154  }
155 
156 
157  template< class DomainFunction, class RangeFunction >
159  ::set ( const DomainFunctionType &u, const OperatorType &op, const RealType &eps )
160  {
161  u_ = &u;
162  op_ = &op;
163  (*op_)( *u_, op_u_ );
164 
165  eps_ = eps;
166  if( eps_ <= RealType( 0 ) )
167  norm_u_ = std::sqrt( u_->scalarProductDofs( *u_ ) );
168  }
169 
170  } // namespace Fem
171 
172 } // namespace Dune
173 
174 #endif // #ifndef DUNE_FEM_AUTOMATICDIFFERENCEOPERATOR_HH
RangeFunction RangeFunctionType
type of discrete function in the operator&#39;s range
Definition: operator.hh:30
DomainFunctionType::RangeFieldType DomainFieldType
field type of the operator&#39;s domain
Definition: differentiableoperator.hh:43
DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType
Definition: automaticdifferenceoperator.hh:48
BaseType::DomainFunctionType DomainFunctionType
type of discrete function in the operator&#39;s domain
Definition: differentiableoperator.hh:38
static double sqrt(const Double &v)
Definition: double.hh:870
operator providing a Jacobian through automatic differentiation
Definition: automaticdifferenceoperator.hh:22
BaseType::RangeFieldType RangeFieldType
Definition: automaticdifferenceoperator.hh:43
Dune::Fem::Operator< DomainFunction, RangeFunction > OperatorType
Definition: automaticdifferenceoperator.hh:39
BaseType::DomainFunctionType DomainFunctionType
Definition: automaticdifferenceoperator.hh:42
AutomaticDifferenceOperator(const RangeFieldType &eps)
Definition: automaticdifferenceoperator.hh:108
RangeFieldType eps_
Definition: automaticdifferenceoperator.hh:70
RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType
Definition: automaticdifferenceoperator.hh:47
BaseType::DomainFieldType DomainFieldType
Definition: automaticdifferenceoperator.hh:44
Definition: automaticdifferenceoperator.hh:30
BaseType::JacobianOperatorType JacobianOperatorType
Definition: automaticdifferenceoperator.hh:99
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition: automaticdifferenceoperator.hh:97
const OperatorType * op_
Definition: automaticdifferenceoperator.hh:64
DomainFunctionType b_
Definition: automaticdifferenceoperator.hh:67
abstract operator
Definition: operator.hh:25
Dune::FieldTraits< RangeFieldType >::real_type RealType
Definition: automaticdifferenceoperator.hh:45
BaseType::RangeFunctionType RangeFunctionType
Definition: automaticdifferenceoperator.hh:93
AutomaticDifferenceOperator(const ParameterReader &parameter=Parameter::container())
Definition: automaticdifferenceoperator.hh:104
Definition: coordinate.hh:4
RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType
Definition: automaticdifferenceoperator.hh:101
BaseType::DomainFieldType DomainFieldType
Definition: automaticdifferenceoperator.hh:96
const std::string name_
Definition: automaticdifferenceoperator.hh:63
BaseType::DomainFunctionType DomainFunctionType
Definition: automaticdifferenceoperator.hh:94
virtual void jacobian(const DomainFunctionType &u, JacobianOperatorType &jOp) const
Definition: automaticdifferenceoperator.hh:112
void set(const DomainFunctionType &u, const OperatorType &op, const RealType &eps)
Definition: automaticdifferenceoperator.hh:159
const DomainFunctionType * u_
Definition: automaticdifferenceoperator.hh:65
static ParameterContainer & container()
Definition: io/parameter.hh:190
DomainFunction::RangeFieldType DomainFieldType
field type of the operator&#39;s domain
Definition: operator.hh:33
RangeFunction::RangeFieldType RangeFieldType
field type of the operator&#39;s range
Definition: operator.hh:35
BaseType::RangeFunctionType RangeFunctionType
type of discrete function in the operator&#39;s range
Definition: differentiableoperator.hh:40
abstract affine-linear operator
Definition: operator.hh:70
RangeFieldType norm_u_
Definition: automaticdifferenceoperator.hh:71
AutomaticDifferenceLinearOperator(const std::string &name, const DomainSpaceType &dSpace, const RangeSpaceType &rSpace)
Definition: automaticdifferenceoperator.hh:50
virtual void operator()(const DomainFunctionType &arg, RangeFunctionType &dest) const
application operator
Definition: automaticdifferenceoperator.hh:128
abstract differentiable operator
Definition: differentiableoperator.hh:26
RangeFunctionType op_u_
Definition: automaticdifferenceoperator.hh:68
RangeFunctionType::RangeFieldType RangeFieldType
field type of the operator&#39;s range
Definition: differentiableoperator.hh:45
BaseType::RangeFunctionType RangeFunctionType
Definition: automaticdifferenceoperator.hh:41
BaseType::RangeFieldType RangeFieldType
Definition: automaticdifferenceoperator.hh:95
DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType
Definition: automaticdifferenceoperator.hh:102
DomainFunction DomainFunctionType
type of discrete function in the operator&#39;s domain
Definition: operator.hh:28