1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2010 - 2020 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 
17 #ifndef dealii_operator_h
18 #define dealii_operator_h
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/algorithms/any_data.h>
23 
24 #include <deal.II/base/event.h>
25 
26 #include <fstream>
27 
28 DEAL_II_NAMESPACE_OPEN
29 
30 /**
31  * Namespace containing numerical algorithms in a unified form.
32  *
33  * All algorithmic classes in this namespace are derived from either Operator
34  * or OutputOperator, depending on whether they return a value or not. See the
35  * documentation of those classes for more detailed information on how to use
36  * them.
37  */
38 namespace Algorithms
39 {
40   /**
41    * @todo Update this documentation and the one of Operator
42    *
43    * The abstract base class of all algorithms in this library. An operator is
44    * an object with an operator(), which transforms a set of named vectors
45    * into another set of named vectors.
46    *
47    * Furthermore, an operator can be notified of parameter changes by the
48    * calling routine. The outer iteration can notify() the Operator of an
49    * Event, which could be for instance a change of mesh, a different time
50    * step size or too slow convergence of Newton's method, which would then
51    * trigger reassembling of a matrix or similar things.
52    *
53    * <h3>Usage for nested iterations</h3>
54    *
55    * This is probably the most prominent use for Operator, where an outer
56    * iterative method calls an inner solver and so on. Typically, the
57    * innermost method in such a nested system will have to compute a residual
58    * using values from all outer iterations. Since the depth and order of such
59    * a nesting is hardly predictable when designing a general tool, we use
60    * AnyData to access these vectors. Typically, the first vector in
61    * <tt>out</tt> contains the start vector when operator()() is called, and
62    * the solution when the function returns. The object <tt>in</tt> is
63    * providing additional information and forwarded to the inner Operator
64    * objects of the nested iteration.
65    */
66   class OperatorBase : public Subscriptor
67   {
68   public:
69     /**
70      * The virtual destructor.
71      */
72     virtual ~OperatorBase() override = default;
73 
74     /**
75      * The actual operation, which is implemented in a derived class.
76      */
77     virtual void
78     operator()(AnyData &out, const AnyData &in) = 0;
79 
80     /**
81      * Register an event triggered by an outer iteration.
82      */
83     virtual void
84     notify(const Event &);
85 
86     /**
87      * Clear all #notifications.
88      */
89     void
90     clear_events();
91 
92   protected:
93     /**
94      * Accumulate events here. If any of those is set, the function solve() of
95      * a terminal application must take care of reassembling the matrix.
96      */
97     Event notifications;
98   };
99 
100   /**
101    * An unary operator base class, intended to output the vectors in AnyData
102    * in each step of an iteration.
103    */
104   template <typename VectorType>
105   class OutputOperator : public Subscriptor
106   {
107   public:
108     /**
109      * Constructor initializing member variables with invalid data.
110      */
111     OutputOperator();
112 
113     /**
114      * The copy constructor is deleted since objects of this class
115      * should not be copied.
116      */
117     OutputOperator(const OutputOperator<VectorType> &) = delete;
118 
119     /**
120      * Empty virtual destructor.
121      */
122     virtual ~OutputOperator() override = default;
123 
124     /**
125      * Set the stream @p os to which data is written. If no stream is selected
126      * with this function, data goes to @p deallog.
127      */
128     void
129     initialize_stream(std::ostream &stream);
130 
131     /**
132      * Set the current step.
133      */
134     void
135     set_step(const unsigned int step);
136 
137     /**
138      * Output all the vectors in AnyData.
139      */
140     virtual OutputOperator<VectorType> &
141     operator<<(const AnyData &vectors);
142 
143   protected:
144     unsigned int step;
145 
146   private:
147     std::ostream *os;
148   };
149 
150   template <typename VectorType>
151   inline void
set_step(const unsigned int s)152   OutputOperator<VectorType>::set_step(const unsigned int s)
153   {
154     step = s;
155   }
156 
157 
158   /**
159    * Set the step number in OutputOperator by shifting an integer value.
160    *
161    * @relatesalso OutputOperator
162    */
163   template <typename VectorType>
164   inline OutputOperator<VectorType> &
165   operator<<(OutputOperator<VectorType> &out, unsigned int step)
166   {
167     out.set_step(step);
168     return out;
169   }
170 } // namespace Algorithms
171 
172 DEAL_II_NAMESPACE_CLOSE
173 
174 #endif
175