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