Flow123d  jenkins-Flow123d-linux-release-multijob-198
mass_balance.hh
Go to the documentation of this file.
1 #ifndef MASS_BALANCE_HH_
2 #define MASS_BALANCE_HH_
3 
4 
5 #include "la/distribution.hh"
6 #include "transport/substance.hh"
7 #include "petscmat.h"
8 #include "fields/unit_si.hh"
9 
10 class RegionDB;
11 
12 
13 
14 
15 
16 /**
17  * Design of balance class - serves as storage and writer.
18  * Equations themselves call methods of Balance that add/modify mass, source and flux
19  * of various quantities and generate output.
20  *
21  * One instance of Balance can handle several conservative quantities of the same type
22  * (e.g. mass of several substances or their phases).
23  *
24  * The mass, flux and source are calculated as follows:
25  *
26  * m(q,c,r) = ( M'(q,c) * solution )[r]
27  * f(q,c,r) = ( R' * ( F(q,c) * solution + fv(q,c) ) )[r]
28  * s(q,c,r) = ( S'(q,c) * solution + sv(q,c) )[r]
29  *
30  * where M' stands for matrix transpose,
31  *
32  * m(q,c,r)...mass of q-th substance's c-th component in region r
33  * f(q,c,r)...flux of q-th substance's c-th component in region r
34  * s(q,c,r)...source of q-th substance's c-th component in region r
35  *
36  * and
37  *
38  * M(q,c)...region_mass_matrix_[q*quantities_.size() + c] n_dofs x n_bulk_regions
39  * F(q,c)...be_flux_matrix_[q*quantities_.size() + c] n_boundary_edges x n_dofs
40  * S(q,c)...region_source_matrix_[q*quantities_.size() + c] n_dofs x n_bulk_regions
41  * SV(q,c)..region_source_rhs_[q*quantities_.size() + c] n_dofs x n_bulk_regions
42  * fv(q,c)..be_flux_vec_[q*quantities_.size() + c] n_boundary_edges
43  * sv(q,c)..region_source_vec_[q*quantities_.size() + c] n_bulk_regions
44  * R........region_be_matrix_ n_boundary_edges x n_boundary_regions
45  *
46  * Note that it holds:
47  *
48  * sv(q,c) = column sum of SV(q,c)
49  *
50  * Except for that, we also provide information on positive/negative flux and source:
51  *
52  * fp(q,c,r) = ( R' * EFP(q,c) )[r], EFP(q,c)[e] = max{ 0, ( F(q,c) * solution + fv(q,c) )[e] }
53  * fn(q,c,r) = ( R' * EFN(q,c) )[r], EFN(q,c)[e] = min{ 0, ( F(q,c) * solution + fv(q,c) )[e] }
54  * sp(q,c,r) = sum_{i in DOFS } max{ 0, ( S(q,c)[i,r] * solution[i] + SV(q,c)[i,r] ) }
55  * sn(q,c,r) = sum_{i in DOFS } min{ 0, ( S(q,c)[i,r] * solution[i] + SV(q,c)[i,r] ) }
56  *
57  * where
58  *
59  * fp(q,c,r)...positive (outward) flux of q-th quantity's c-th component in region r
60  * fn(q,c,r)...negative (inward) flux of q-th quantity's c-th component in region r
61  * sp(q,c,r)...positive source (spring) of q-th quantity's c-th component in region r
62  * sn(q,c,r)...negative source (sink) of q-th quantity's c-th component in region r
63  *
64  * Remark: The matrix R is needed only for calculation of signed fluxes.
65  * The reason is that to determine sign, we decompose flux to sum of local contributions
66  * per each boundary element and check its sign. It is not possible to decompose flux
67  * using shape functions, since their normal derivatives may have any sign.
68  *
69  *
70  *
71  * Output values (if not relevant, zero is supplied):
72  *
73  * #time bulk_region quantity 0 0 0 mass source source_in source_out 0 0 0
74  * #time boundary_region quantity flux flux_in flux_out 0 0 0 0 0 0 0
75  * #time ALL quantity flux flux_in flux_out mass source source_in source_out integrated_flux integrated_source error
76  *
77  * error = current_mass - (initial_mass + integrated_source - integrated_flux)
78  *
79  */
80 class Balance {
81 public:
82 
83  /**
84  * Class for storing internal data about conservative quantities handled by the Balance object.
85  * In the future we may store additional data or support definition of derived quantities
86  * (e.g. linear combinations of quantities).
87  */
88  class Quantity {
89  public:
90 
91  Quantity(const unsigned int index, const string &name)
92  : name_(name),
93  index_(index)
94  {}
95 
96  /// Name of quantity (for output).
97  string name_;
98 
99  /// Internal index within list of quantities.
100  const unsigned int index_;
101 
102  };
103 
104  /**
105  * Possible formats of output file.
106  */
108  {
109  legacy,//!< legacy
110  txt, //!< csv
111  gnuplot//!< gnuplot
112  };
113 
114  /// Main balance input record type.
116 
117  /// Input selection for file format.
119 
120  /**
121  * Constructor.
122  * @param file_prefix Prefix of output file name.
123  * @param mesh Mesh.
124  * @param el_ds Distribution of elements.
125  * @param el_4_loc Local to global element numbering.
126  * @param in_rec Input record of balance.
127  */
128  Balance(const std::string &file_prefix,
129  const Mesh *mesh,
130  const Distribution *el_ds,
131  const int *el_4_loc,
132  const Input::Record &in_rec);
133 
134  ~Balance();
135 
136  /// Setter for units of conserved quantities.
137  void units(const UnitSI &unit) { units_ = unit; units_.undef(false); }
138 
139  /// Getter for cumulative_.
140  inline bool cumulative() const { return cumulative_; }
141 
142  /**
143  * Define a single conservative quantity.
144  * @param name Name of the quantity.
145  * @return Quantity's internal index.
146  */
147  unsigned int add_quantity(const string &name);
148 
149  /**
150  * Define a set of conservative quantities.
151  * @param names List of quantities' names.
152  * @return List of quantities' indices.
153  */
155 
156  /**
157  * Allocates matrices and vectors for balance.
158  * @param n_loc_dofs Number of solution dofs on the local process.
159  * @param max_dofs_per_boundary Number of dofs contributing to one boundary edge.
160  */
161  void allocate(unsigned int n_loc_dofs, unsigned int max_dofs_per_boundary);
162 
163  /**
164  * This method must be called before assembling the matrix for computing mass.
165  * It actually erases the matrix.
166  */
167  void start_mass_assembly(unsigned int quantity_idx);
168 
169  /// Variant of the start_mass_assembly() method for a set of quantities.
171  {
172  for (auto idx : q_idx_vec)
173  start_mass_assembly(idx);
174  }
175 
176  /**
177  * This method must be called before assembling the matrix and vector for fluxes.
178  * It actually erases the matrix and vector.
179  */
180  void start_flux_assembly(unsigned int quantity_idx);
181 
182  /// Variant of the start_flux_assembly() method for a set of quantities.
184  {
185  for (auto idx : q_idx_vec)
186  start_flux_assembly(idx);
187  }
188 
189  /**
190  * This method must be called before assembling the matrix and vectors for sources.
191  * It actually erases the matrix and vectors.
192  */
193  void start_source_assembly(unsigned int quantity_idx);
194 
195  /// Variant of the start_source_assembly() method for a set of quantities.
197  {
198  for (auto idx : q_idx_vec)
200  }
201 
202  /**
203  * Adds elements into matrix for computing mass.
204  * @param quantity_idx Index of quantity.
205  * @param region_idx Index of bulk region.
206  * @param n_dofs Number of dofs to be added.
207  * @param dof_indices Dof indices to be added.
208  * @param values Values to be added.
209  */
210  void add_mass_matrix_values(unsigned int quantity_idx,
211  unsigned int region_idx,
212  const std::vector<int> &dof_indices,
213  const std::vector<double> &values);
214 
215  /**
216  * Adds elements into matrix for computing flux.
217  * @param quantity_idx Index of quantity.
218  * @param elem_idx Local index of boundary edge.
219  * @param n_dofs Number of dofs to be added.
220  * @param dof_indices Dof indices to be added.
221  * @param values Values to be added.
222  */
223  void add_flux_matrix_values(unsigned int quantity_idx,
224  unsigned int elem_idx,
225  const std::vector<int> &dof_indices,
226  const std::vector<double> &values);
227 
228  /**
229  * Adds elements into matrix for computing source.
230  * @param quantity_idx Index of quantity.
231  * @param region_idx Index of bulk region.
232  * @param n_dofs Number of dofs to be added.
233  * @param dof_indices Dof indices to be added.
234  * @param values Values to be added.
235  */
236  void add_source_matrix_values(unsigned int quantity_idx,
237  unsigned int region_idx,
238  const std::vector<int> &dof_indices,
239  const std::vector<double> &values);
240 
241  /**
242  * Adds element into vector for computing flux.
243  * @param quantity_idx Index of quantity.
244  * @param elem_idx Local index of boundary edge.
245  * @param value Value to be added.
246  */
247  void add_flux_vec_value(unsigned int quantity_idx,
248  unsigned int elem_idx,
249  double value);
250 
251  /**
252  * Adds elements into vector for computing source.
253  * @param quantity_idx Index of quantity.
254  * @param region_idx Index of bulk region.
255  * @param n_dofs Number of dofs to be added.
256  * @param dof_indices Dof indices to be added.
257  * @param values Values to be added.
258  */
259  void add_source_rhs_values(unsigned int quantity_idx,
260  unsigned int region_idx,
261  const std::vector<int> &dof_values,
262  const std::vector<double> &values);
263 
264  /// This method must be called after assembling the matrix for computing mass.
265  void finish_mass_assembly(unsigned int quantity_idx);
266 
267  /// Variant of the finish_mass_assembly() method for a set of quantities.
269  {
270  for (auto idx : q_idx_vec)
272  }
273 
274  /// This method must be called after assembling the matrix and vector for computing flux.
275  void finish_flux_assembly(unsigned int quantity_idx);
276 
277  /// Variant of the finish_flux_assembly() method for a set of quantities.
279  {
280  for (auto idx : q_idx_vec)
282  }
283 
284  /// This method must be called after assembling the matrix and vectors for computing source.
285  void finish_source_assembly(unsigned int quantity_idx);
286 
287  /// Variant of the finish_source_assembly() method for a set of quantities.
289  {
290  for (auto idx : q_idx_vec)
292  }
293 
294  /**
295  * Updates cumulative quantities for balance.
296  * This method can be called in substeps even if no output is generated.
297  * It calculates the sum of flux and source over time interval.
298  * @param quantity_idx Index of quantity.
299  * @param solution Solution vector.
300  * @param dt Actual time step.
301  */
302  void calculate_cumulative_sources(unsigned int quantity_idx,
303  const Vec &solution,
304  double dt);
305 
306  /**
307  * Updates cumulative quantities for balance.
308  * This method can be called in substeps even if no output is generated.
309  * It calculates the sum of flux and source over time interval.
310  * @param quantity_idx Index of quantity.
311  * @param solution Solution vector.
312  * @param dt Actual time step.
313  */
314  void calculate_cumulative_fluxes(unsigned int quantity_idx,
315  const Vec &solution,
316  double dt);
317 
318  /**
319  * Calculates actual mass and save it to given vector.
320  * @param quantity_idx Index of quantity.
321  * @param solution Solution vector.
322  * @param output_array Vector of output masses per region.
323  */
324  void calculate_mass(unsigned int quantity_idx,
325  const Vec &solution,
326  vector<double> &output_array);
327 
328  /**
329  * Calculates actual mass and save it to internal vector.
330  * @param quantity_idx Index of quantity.
331  * @param solution Solution vector.
332  */
333  void calculate_mass(unsigned int quantity_idx,
334  const Vec &solution)
335  {
336  calculate_mass(quantity_idx, solution, masses_[quantity_idx]);
337  }
338 
339  /**
340  * Calculates actual flux.
341  * @param quantity_idx Index of quantity.
342  * @param solution Solution vector.
343  */
344  void calculate_flux(unsigned int quantity_idx,
345  const Vec &solution);
346 
347  /**
348  * Calculates actual source.
349  * @param quantity_idx Index of quantity.
350  * @param solution Solution vector.
351  */
352  void calculate_source(unsigned int quantity_idx,
353  const Vec &solution);
354 
355  /**
356  * Adds provided values to the cumulative sources.
357  * @param quantity_idx Index of quantity.
358  * @param sources Sources per region.
359  * @param dt Actual time step.
360  */
361  void add_cumulative_source(unsigned int quantity_idx, double source);
362 
363  /// Perform output to file for given time instant.
364  void output(double time);
365 
366 private:
367  /// Size of column in output (used if delimiter is space)
368  static const unsigned int output_column_width = 20;
369 
370  /// Perform output in old format (for compatibility)
371  void output_legacy(double time);
372 
373  /// Perform output in csv format
374  void output_csv(double time, char delimiter, const std::string& comment_string, unsigned int repeat = 0);
375 
376  /// Return part of output represented by zero values. Count of zero values is given by cnt parameter.
377  std::string csv_zero_vals(unsigned int cnt, char delimiter);
378 
379  /// Print output header
380  void format_csv_output_header(char delimiter, const std::string& comment_string);
381 
382  /// Format string value of csv output. Wrap string into quotes and if delimiter is space, align text to column.
383  std::string format_csv_val(std::string val, char delimiter, bool initial = false);
384 
385  /// Format double value of csv output. If delimiter is space, align text to column.
386  std::string format_csv_val(double val, char delimiter, bool initial = false);
387 
388 
389  /// Handle for file for output of balance and total fluxes over individual regions and region sets.
390  ofstream output_;
391 
392  /// Format of output file.
394 
395  /// Names of conserved quantities.
397 
398  /// Database of bulk and boundary regions.
400 
401  /// Units of conserved quantities.
403 
404 
405  /// Matrices for calculation of mass (n_dofs x n_bulk_regions).
407 
408  /// Matrices for calculation of flux (n_boundary_edges x n_dofs).
410 
411  /// Matrices for calculation of source (n_dofs x n_bulk_regions).
413 
414  /// Matrices for calculation of signed source (n_dofs x n_bulk_regions).
416 
417  /// Vectors for calculation of flux (n_boundary_edges).
419 
420  /// Vectors for calculation of source (n_bulk_regions).
422 
423  /**
424  * Auxiliary matrix for transfer of quantities between boundary edges and regions
425  * (n_boundary_edges x n_boundary_regions).
426  */
428 
429  /// auxiliary vectors for summation of matrix columns
431 
432  /// Number of boundary region for each local boundary edge.
434 
435  /// Offset for local part of vector of boundary edges.
437 
438 
439  // Vectors storing mass and balances of fluxes and volumes.
440  // substance, phase, region
448 
449  // Sums of the above vectors over phases and regions
458 
459  // time integrated quantities
464 
465  /// initial time
467 
468  /// time of last calculated balance
469  double last_time_;
470 
471  /// true before calculating the mass at initial time, otherwise false
472  bool initial_;
473 
474  /// if true then cumulative balance is computed
476 
477  /// true before allocating necessary internal structures (Petsc matrices etc.)
479 
480  /// MPI rank.
481  int rank_;
482 
483  /// hold count of line printed into output_
484  unsigned int output_line_counter_;
485 
486 };
487 
488 
489 
490 
491 
492 #endif // MASS_BALANCE_HH_
UnitSI units_
Units of conserved quantities.
void calculate_cumulative_sources(unsigned int quantity_idx, const Vec &solution, double dt)
std::vector< double > integrated_sources_
unsigned int add_quantity(const string &name)
std::vector< double > sum_fluxes_out_
void calculate_mass(unsigned int quantity_idx, const Vec &solution, vector< double > &output_array)
void allocate(unsigned int n_loc_dofs, unsigned int max_dofs_per_boundary)
double initial_time_
initial time
void calculate_cumulative_fluxes(unsigned int quantity_idx, const Vec &solution, double dt)
void finish_source_assembly(unsigned int quantity_idx)
This method must be called after assembling the matrix and vectors for computing source.
bool initial_
true before calculating the mass at initial time, otherwise false
void add_flux_vec_value(unsigned int quantity_idx, unsigned int elem_idx, double value)
void start_mass_assembly(std::vector< unsigned int > q_idx_vec)
Variant of the start_mass_assembly() method for a set of quantities.
std::vector< std::vector< double > > sources_in_
static Input::Type::Record input_type
Main balance input record type.
void add_cumulative_source(unsigned int quantity_idx, double source)
void finish_mass_assembly(std::vector< unsigned int > q_idx_vec)
Variant of the finish_mass_assembly() method for a set of quantities.
std::vector< std::vector< double > > fluxes_in_
std::vector< double > sum_fluxes_in_
std::vector< std::vector< double > > fluxes_out_
Balance(const std::string &file_prefix, const Mesh *mesh, const Distribution *el_ds, const int *el_4_loc, const Input::Record &in_rec)
Definition: mass_balance.cc:67
Vec ones_
auxiliary vectors for summation of matrix columns
Mat * region_source_rhs_
Matrices for calculation of signed source (n_dofs x n_bulk_regions).
Definition: mesh.h:109
void add_mass_matrix_values(unsigned int quantity_idx, unsigned int region_idx, const std::vector< int > &dof_indices, const std::vector< double > &values)
ofstream output_
Handle for file for output of balance and total fluxes over individual regions and region sets...
Vec ones_be_
bool cumulative() const
Getter for cumulative_.
void output_legacy(double time)
Perform output in old format (for compatibility)
Mat region_be_matrix_
bool allocation_done_
true before allocating necessary internal structures (Petsc matrices etc.)
const RegionDB & regions_
Database of bulk and boundary regions.
std::vector< double > sum_fluxes_
string name_
Name of quantity (for output).
Definition: mass_balance.hh:97
std::vector< double > increment_sources_
const unsigned int index_
Internal index within list of quantities.
Vec * be_flux_vec_
Vectors for calculation of flux (n_boundary_edges).
std::vector< double > integrated_fluxes_
std::vector< Quantity > quantities_
Names of conserved quantities.
std::string csv_zero_vals(unsigned int cnt, char delimiter)
Return part of output represented by zero values. Count of zero values is given by cnt parameter...
std::vector< std::vector< double > > sources_out_
Mat * be_flux_matrix_
Matrices for calculation of flux (n_boundary_edges x n_dofs).
double last_time_
time of last calculated balance
void calculate_mass(unsigned int quantity_idx, const Vec &solution)
void add_source_rhs_values(unsigned int quantity_idx, unsigned int region_idx, const std::vector< int > &dof_values, const std::vector< double > &values)
std::vector< std::vector< double > > fluxes_
void calculate_source(unsigned int quantity_idx, const Vec &solution)
void add_flux_matrix_values(unsigned int quantity_idx, unsigned int elem_idx, const std::vector< int > &dof_indices, const std::vector< double > &values)
void finish_mass_assembly(unsigned int quantity_idx)
This method must be called after assembling the matrix for computing mass.
void finish_flux_assembly(std::vector< unsigned int > q_idx_vec)
Variant of the finish_flux_assembly() method for a set of quantities.
void calculate_flux(unsigned int quantity_idx, const Vec &solution)
void format_csv_output_header(char delimiter, const std::string &comment_string)
Print output header.
int rank_
MPI rank.
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
void start_flux_assembly(std::vector< unsigned int > q_idx_vec)
Variant of the start_flux_assembly() method for a set of quantities.
Mat * region_mass_matrix_
Matrices for calculation of mass (n_dofs x n_bulk_regions).
std::vector< std::vector< double > > sources_
std::vector< double > sum_sources_out_
bool cumulative_
if true then cumulative balance is computed
Mat * region_source_matrix_
Matrices for calculation of source (n_dofs x n_bulk_regions).
std::vector< double > increment_fluxes_
void finish_source_assembly(std::vector< unsigned int > q_idx_vec)
Variant of the finish_source_assembly() method for a set of quantities.
void output_csv(double time, char delimiter, const std::string &comment_string, unsigned int repeat=0)
Perform output in csv format.
std::vector< unsigned int > add_quantities(const std::vector< string > &names)
Support classes for parallel programing.
std::vector< double > sum_sources_
void start_flux_assembly(unsigned int quantity_idx)
std::vector< double > initial_mass_
static const unsigned int output_column_width
Size of column in output (used if delimiter is space)
Quantity(const unsigned int index, const string &name)
Definition: mass_balance.hh:91
void finish_flux_assembly(unsigned int quantity_idx)
This method must be called after assembling the matrix and vector for computing flux.
std::vector< unsigned int > be_regions_
Number of boundary region for each local boundary edge.
OutputFormat output_format_
Format of output file.
Classes for storing substance data.
void units(const UnitSI &unit)
Setter for units of conserved quantities.
int be_offset_
Offset for local part of vector of boundary edges.
std::vector< std::vector< double > > masses_
void start_source_assembly(std::vector< unsigned int > q_idx_vec)
Variant of the start_source_assembly() method for a set of quantities.
Vec * region_source_vec_
Vectors for calculation of source (n_bulk_regions).
void start_mass_assembly(unsigned int quantity_idx)
Record type proxy class.
Definition: type_record.hh:169
std::vector< double > sum_masses_
unsigned int output_line_counter_
hold count of line printed into output_
void output(double time)
Perform output to file for given time instant.
Class for representation SI units of Fields.
Definition: unit_si.hh:31
void add_source_matrix_values(unsigned int quantity_idx, unsigned int region_idx, const std::vector< int > &dof_indices, const std::vector< double > &values)
void undef(bool val=true)
Definition: unit_si.cc:163
void start_source_assembly(unsigned int quantity_idx)
Template for classes storing finite set of named values.
static Input::Type::Selection format_selection_input_type
Input selection for file format.
std::string format_csv_val(std::string val, char delimiter, bool initial=false)
Format string value of csv output. Wrap string into quotes and if delimiter is space, align text to column.
std::vector< double > sum_sources_in_