Flow123d
equation.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2007 Technical University of Liberec. All rights reserved.
4  *
5  * Please make a following refer to Flow123d on your project site if you use the program for any purpose,
6  * especially for academic research:
7  * Flow123d, Research Centre: Advanced Remedial Technologies, Technical University of Liberec, Czech Republic
8  *
9  * This program is free software; you can redistribute it and/or modify it under the terms
10  * of the GNU General Public License version 3 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along with this program; if not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
18  *
19  *
20  * $Id$
21  * $Revision$
22  * $LastChangedBy$
23  * $LastChangedDate$
24  *
25  * @file
26  * @brief Abstract base class for equation clasess.
27  *
28  * @author Jan Brezina
29  */
30 
31 #ifndef EQUATION_HH_
32 #define EQUATION_HH_
33 
34 
35 #include <limits>
36 #include "time_governor.hh"
37 #include "time_marks.hh"
38 #include "input/accessors.hh"
39 
40 #include <petscvec.h>
41 
42 class Mesh;
43 class Region;
44 class FieldSet;
46 
47 
48 namespace Input {
49  class Record;
50 }
51 
52 /**
53  * Class EquationBase is abstract base class for a general time dependent model. This class should provide general interface
54  * that can be used for general coupling of various particular models. By a model we mean a discrete solver of
55  * an partial or ordinary differential equation. Result of the model at one discrete time level should be a discrete field class (not yet implemented).
56  * Until we have field classes we only provide method get_solution_vector(), which returns pointer to sequential C array with linear combination of
57  * base functions that represents the solution.
58  *
59  * Computation of one time step (method compute_one_step() ) is split into update_solution() and choose_next_time().
60  *
61  * This class does not implement any constructor. In particular it does not initialize mesh and time. This has to be done in the constructor
62  * of particular child class.
63  *
64  * Any constructor of child class should set solved = true. We assume, that after initialization an equation object stay solve in init time. For the first time step
65  * one calls method chose_next_time() which setup time frame of the first time step.
66  *
67  * TODO: clarify initialization of data members
68  *
69  */
70 class EquationBase {
71 public:
72 
73  /**
74  * Default constructor. Sets all virtual methods empty. Necessary to make tests fixtures for equations.
75  * TODO:
76  * Replace setting all in constructor with appropriate getters and setters.
77  * Make appropriate checks if key ingredients are initialized.
78  */
79  EquationBase();
80 
81  /**
82  * Common initialization constructor.
83  */
84  EquationBase(Mesh &mesh, const Input::Record in_rec);
85 
86  /**
87  * Require virtual destructor also for child classes.
88  */
89  virtual ~EquationBase() {};
90 
91  /**
92  * Initialization of the solution in the zero time.
93  * There is lot of things that can not be done in the constructor
94  * since we have not fully initialized fields yet. Fields coming from coupling
95  * has to be set after the constructor and before zero_time_step.
96  */
97  virtual void zero_time_step() {
98  if (equation_empty_) DBGMSG("Calling 'zero_time_step' of empty equation '%s'.\n",typeid(*this).name());
99  else DBGMSG("Method 'zero_time_step' of '%s' is not implemented.\n",typeid(*this).name());
100  }
101 
102  /**
103  * Calculation of the next time step and its output.
104  */
105  virtual void update_solution() {
106  if (equation_empty_) DBGMSG("Calling 'update_solution' of empty equation '%s'.\n",typeid(*this).name());
107  else DBGMSG("Method 'update_solution' of '%s' is not implemented.\n",typeid(*this).name());
108  }
109 
110  ///Initialize fields.
111  /**
112  * All members that are needed to set fields must be set at this moment (e.g. number of components).
113  */
114  virtual void initialize() {
115  if (equation_empty_) DBGMSG("Calling 'initialize' of empty equation '%s'.\n",typeid(*this).name());
116  else DBGMSG("Method 'initialize' of '%s' is not implemented.\n",typeid(*this).name());
117  }
118 
119  /**
120  * Computation of one time step is split into update_solution() and choose_next_time() in order to allow dependency of the next time step
121  * on other coupled models.
122  */
123 // virtual void compute_one_step() {
124 // update_solution();
125 // choose_next_time();
126 // }
127 
128  /**
129  * Fix the next discrete time for computation.
130  * Can be rewritten in child class to set possible constrains
131  * according to possible equation coefficients or other data which can be result of another model.
132  *
133  */
134  virtual void choose_next_time()
136 
137  /**
138  * Set external upper time step constrain for time governor of the equation.
139  */
140  virtual void set_time_upper_constraint(double dt)
142 
143  /**
144  * Set external lower time step constrain for time governor of the equation.
145  */
146  virtual void set_time_lower_constraint(double dt)
148 
149  /**
150  * Basic getter method returns constant TimeGovernor reference which provides full read access to the time information.
151  */
152  inline TimeGovernor const &time()
153  {
154  ASSERT( time_,"Time governor was not created.\n");
155  return *time_;
156  }
157 
158  /**
159  * Set time governor.
160  *
161  * Used to set pointer to common time governor (e.g. in Transport Operator Splitting, Reaction).
162  */
163  virtual void set_time_governor(TimeGovernor &time);
164 
165  /**
166  * Most actual planned time for solution.
167  */
168  inline double planned_time()
169  { return time_->estimate_time(); }
170 
171  /**
172  * Time of actual solution returned by get_solution_vector().
173  */
174  inline double solved_time()
175  { return time_->t(); }
176 
177  /**
178  * This getter method provides the computational mesh currently used by the model.
179  */
180  inline Mesh &mesh()
181  {
182  return *mesh_;
183  }
184 
185  /**
186  * Getter for equation time mark type.
187  */
189  {
190  return time().equation_mark_type();
191  }
192 
193  /**
194  * Return reference to the equation data object containing all fields
195  * that the equation needs or produce.
196  */
198  {
199  ASSERT(eq_data_, "The equation %s did not set eq_data_ pointer.\n", input_record_.address_string().c_str());
200  return *eq_data_;
201  }
202 
203  /**
204  * Child class have to implement getter for sequential solution vector.
205  * DEPRECATED
206  */
207  virtual void get_solution_vector(double * &vector, unsigned int &size)
208  { ASSERT(0, "If using, needs to be implemented in ancestors!"); };
209 
210  /**
211  * Child class have to implement getter for parallel solution vector.
212  * DEPRECATED
213  */
215  { ASSERT(0, "If using, needs to be implemented in ancestors!"); };
216 
217  /**
218  * @brief Write computed fields.
219  */
220  virtual void output_data() {
221  if (equation_empty_) DBGMSG("Calling 'output_data' of empty equation '%s'.\n",typeid(*this).name());
222  else DBGMSG("Method 'output_data' of '%s' is not implemented.\n",typeid(*this).name());
223  }
224 
225 protected:
226  bool equation_empty_; ///< flag is true if only default constructor was called
229  //TimeMark::Type equation_mark_type_;
231 
232  /**
233  * Pointer to the equation data object. Every particular equation is responsible
234  * to set the pointer in its constructor. This is used by the general method
235  * EqData::data(). This approach is simpler than making EqData::data() a virtual method.
236  */
238 };
239 
240 
241 
242 
243 
244 
245 /** OBSOLETE
246  * Demonstration of empty equation class, which can be used if user turns off some equation in the model.
247  */
248 // class EquationNothing : public EquationBase {
249 //
250 // public:
251 // EquationNothing(Mesh &mesh);
252 //
253 // void get_solution_vector(double * &vector, unsigned int &size) override
254 // {
255 // vector = NULL;
256 // size = 0;
257 // }
258 //
259 // void get_parallel_solution_vector(Vec &vector) override {};
260 //
261 // virtual ~EquationNothing() {};
262 //
263 // };
264 
265 
266 #endif /* EQUATION_HH_ */