Flow123d  build_with_4.0.3-01443f6
equation.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file equation.hh
15  * @brief Abstract base class for equation clasess.
16  * @author Jan Brezina
17  */
18 
19 #ifndef EQUATION_HH_
20 #define EQUATION_HH_
21 
22 
23 #include <petscvec.h> // for Vec
24 #include <memory> // for shared_ptr
25 #include <string> // for basic_string
26 #include <typeinfo> // for type_info
27 #include "input/accessors.hh" // for Record
28 #include "system/exceptions.hh" // for ExcAssertMsg::...
29 #include "system/asserts.hh" // for ASSERT_PERMANENT, ...
30 #include "system/logger.hh" // for Logger, DebugOut
31 #include "tools/time_governor.hh" // for TimeGovernor
32 #include "tools/time_marks.hh" // for TimeMark, Time...
33 class Balance;
34 class FieldSet;
35 class Mesh;
36 
37 
38 /**
39  * Class EquationBase is abstract base class for a general time dependent model. This class should provide general interface
40  * that can be used for general coupling of various particular models. By a model we mean a discrete solver of
41  * an partial or ordinary differential equation. Result of the model at one discrete time level should be a discrete field class (not yet implemented).
42  * Until we have field classes we only provide method get_solution_vector(), which returns pointer to sequential C array with linear combination of
43  * base functions that represents the solution.
44  *
45  * Computation of one time step (method compute_one_step() ) is split into update_solution() and choose_next_time().
46  *
47  * This class does not implement any constructor. In particular it does not initialize mesh and time. This has to be done in the constructor
48  * of particular child class.
49  *
50  * 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
51  * one calls method chose_next_time() which setup time frame of the first time step.
52  *
53  * TODO: clarify initialization of data members
54  *
55  */
56 class EquationBase {
57 public:
58 
59  /// Template Record with common keys for derived equations.
61 
62  /// Template Record with common key user_fields for derived equations.
63  static Input::Type::Record & user_fields_template(std::string equation_name);
64 
65  /**
66  * Default constructor. Sets all virtual methods empty. Necessary to make tests fixtures for equations.
67  * TODO:
68  * Replace setting all in constructor with appropriate getters and setters.
69  * Make appropriate checks if key ingredients are initialized.
70  */
71  EquationBase();
72 
73  /**
74  * Common initialization constructor.
75  * Implementation of particular equation should set just basic things in the constructor and postpone
76  * its initialization including initialization of its fields to the initialize method. The reason is
77  * that when the equation is part of a coupling the coupling may set some setting of the equation from
78  * the coupling level so that initialization use correct parameters.
79  * TODO: Which mechanism we use to pass setting form the coupling to its equations. Either use dedicated setters
80  * this however prevent generic coupling or use input storage to set data from upper level.
81  */
82  EquationBase(Mesh &mesh, const Input::Record in_rec);
83 
84 
85  /**
86  * This method should initialize fields of the equation.
87  * All members (e.g. number of components) that are necessary for the field initialization must be set
88  * between construction and call of initialize.
89  * After this method the upper level coupling may set sharing of some fields between equations.
90  */
91  virtual void initialize() {
92  if (equation_empty_) DebugOut().fmt("Calling 'initialize' of empty equation '{}'.\n", typeid(*this).name());
93  else DebugOut().fmt("Method 'initialize' of '{}' is not implemented.\n", typeid(*this).name());
94  }
95 
96  /**
97  * Initialization of the solution in the zero time.
98  *
99  * There may be fields that can not be initialized in the initialize method
100  * as they are provided by the coupling. Fields coming from coupling
101  * has to be set after the initialize method and before zero_time_step.
102  */
103  virtual void zero_time_step() {
104  if (equation_empty_) DebugOut().fmt("Calling 'zero_time_step' of empty equation '{}'.\n", typeid(*this).name());
105  else DebugOut().fmt("Method 'zero_time_step' of '{}' is not implemented.\n", typeid(*this).name());
106  }
107 
108 
109  /**
110  * Require virtual destructor also for child classes.
111  */
112  virtual ~EquationBase() {
113  balance_.reset();
114  };
115 
116 
117  /**
118  * Calculation of the next time step and its output.
119  */
120  virtual void update_solution() {
121  if (equation_empty_) DebugOut().fmt("Calling 'update_solution' of empty equation '{}'.\n", typeid(*this).name());
122  else DebugOut().fmt("Method 'update_solution' of '{}' is not implemented.\n", typeid(*this).name());
123  }
124 
125 
126 
127  /**
128  * Fix the next discrete time for computation.
129  * Can be rewritten in child class to set possible constrains
130  * according to possible equation coefficients or other data which can be result of another model.
131  *
132  */
133  virtual void choose_next_time()
135 
136  /**
137  * Set external upper time step constrain for time governor of the equation.
138  */
139  virtual void set_time_upper_constraint(double dt, std::string message)
140  {time_->set_upper_constraint(dt, message);}
141 
142  /**
143  * Set external lower time step constrain for time governor of the equation.
144  */
145  virtual void set_time_lower_constraint(double dt, std::string message)
146  {time_->set_lower_constraint(dt, message);}
147 
148  /**
149  * Basic getter method returns TimeGovernor reference which provides full access to the time information.
150  */
151  inline TimeGovernor &time()
152  {
153  ASSERT_PTR( time_ ).error("Time governor was not created.\n");
154  return *time_;
155  }
156 
157  /**
158  * Set time governor.
159  *
160  * Used to set pointer to common time governor (e.g. in Transport Operator Splitting, Reaction).
161  */
162  virtual void set_time_governor(TimeGovernor &time);
163 
164  /**
165  * Most actual planned time for solution.
166  */
167  inline double planned_time()
168  { return time_->estimate_time(); }
169 
170  /**
171  * Time until which the actual solution is valid.
172  * By default, it returns the actual time of the time governor.
173  * However, it can be overriden by a specific equation.
174  * E.g. it differs in Darcy flow in the steady case.
175  */
176  virtual double solved_time();
177 
178  /**
179  * This getter method provides the computational mesh currently used by the model.
180  */
181  inline Mesh &mesh()
182  {
183  return *mesh_;
184  }
185 
186  /**
187  * This getter method provides the balance object.
188  */
189  inline std::shared_ptr<Balance> balance() const
190  {
191  return balance_;
192  }
193 
194  /**
195  * Getter for equation time mark type.
196  */
198  {
199  return time().equation_mark_type();
200  }
201 
202  /**
203  * Return reference to the equation data object containing all fields
204  * that the equation needs or produce.
205  */
207  {
208  ASSERT_PTR(eq_fieldset_)(input_record_.address_string()).error("The equation did not set eq_fieldset_ pointer.\n");
209  return *eq_fieldset_;
210  }
211 
212  /**
213  * Same as previous but return shared_ptr.
214  */
215  std::shared_ptr<FieldSet> eq_fieldset_ptr()
216  {
217  ASSERT_PTR(eq_fieldset_)(input_record_.address_string()).error("The equation did not set eq_fieldset_ pointer.\n");
218  return eq_fieldset_;
219  }
220 
221  /**
222  * @brief Write computed fields.
223  */
224  virtual void output_data() {
225  if (equation_empty_) DebugOut().fmt("Calling 'output_data' of empty equation '{}'.\n", typeid(*this).name());
226  else DebugOut().fmt("Method 'output_data' of '{}' is not implemented.\n", typeid(*this).name());
227  }
228 
229  /**
230  * Create user defined fields, store them to equation FieldSet and to output FieldSet.
231  *
232  * @param user_fields List of Input::Records defined by user on input.
233  * @param time Start time of simulation (necessary for Field<>::set).
234  * @param output_fields Output FieldSet.
235  */
236  void init_user_fields(Input::Array user_fields, FieldSet &output_fields);
237 
238 protected:
239  bool equation_empty_; ///< flag is true if only default constructor was called
243 
244  /**
245  * Pointer to the equation data object. Every particular equation is responsible
246  * to set the pointer in its constructor. This is used by the general method
247  * EqData::data(). This approach is simpler than making EqData::data() a virtual method.
248  */
249  std::shared_ptr<FieldSet> eq_fieldset_;
250 
251  /// object for calculation and writing the mass balance to file.
252  std::shared_ptr<Balance> balance_;
253 
254 };
255 
256 
257 #endif /* EQUATION_HH_ */
Definitions of ASSERTS.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Definition: asserts.hh:341
std::shared_ptr< Balance > balance() const
Definition: equation.hh:189
Input::Record input_record_
Definition: equation.hh:242
static Input::Type::Record & record_template()
Template Record with common keys for derived equations.
Definition: equation.cc:39
virtual double solved_time()
Definition: equation.cc:79
std::shared_ptr< FieldSet > eq_fieldset_
Definition: equation.hh:249
FieldSet & eq_fieldset()
Definition: equation.hh:206
virtual void output_data()
Write computed fields.
Definition: equation.hh:224
TimeMark::Type mark_type()
Definition: equation.hh:197
virtual void zero_time_step()
Definition: equation.hh:103
std::shared_ptr< FieldSet > eq_fieldset_ptr()
Definition: equation.hh:215
Mesh & mesh()
Definition: equation.hh:181
virtual void initialize()
Definition: equation.hh:91
virtual void set_time_governor(TimeGovernor &time)
Definition: equation.cc:74
void init_user_fields(Input::Array user_fields, FieldSet &output_fields)
Definition: equation.cc:84
bool equation_empty_
flag is true if only default constructor was called
Definition: equation.hh:239
TimeGovernor * time_
Definition: equation.hh:241
virtual void set_time_lower_constraint(double dt, std::string message)
Definition: equation.hh:145
virtual void update_solution()
Definition: equation.hh:120
virtual void set_time_upper_constraint(double dt, std::string message)
Definition: equation.hh:139
virtual void choose_next_time()
Definition: equation.hh:133
static Input::Type::Record & user_fields_template(std::string equation_name)
Template Record with common key user_fields for derived equations.
Definition: equation.cc:46
std::shared_ptr< Balance > balance_
object for calculation and writing the mass balance to file.
Definition: equation.hh:252
double planned_time()
Definition: equation.hh:167
Mesh * mesh_
Definition: equation.hh:240
TimeGovernor & time()
Definition: equation.hh:151
virtual ~EquationBase()
Definition: equation.hh:112
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:159
Accessor to input data conforming to declared Array.
Definition: accessors.hh:566
Accessor to the data with type Type::Record.
Definition: accessors.hh:291
string address_string() const
Definition: accessors.cc:184
Record type proxy class.
Definition: type_record.hh:182
Definition: mesh.h:362
Basic time management functionality for unsteady (and steady) solvers (class Equation).
int set_lower_constraint(double lower, std::string message)
Sets lower constraint for the next time step estimating.
int set_upper_constraint(double upper, std::string message)
Sets upper constraint for the next time step estimating.
TimeMark::Type equation_mark_type() const
double estimate_time() const
double fix_dt_until_mark()
Fixing time step until fixed time mark.
#define DebugOut()
Macro defining 'debug' record of log.
Definition: logger.hh:284
Basic time management class.