Flow123d  jenkins-Flow123d-linux-release-multijob-282
transport_operator_splitting.cc
Go to the documentation of this file.
1 /*
2  * transport_operator_splitting.cc
3  *
4  * Created on: May 21, 2011
5  * Author: jiri
6  */
7 
8 #include <iostream>
9 #include <iomanip>
10 
11 #include "system/system.hh"
12 #include "system/sys_profiler.hh"
13 #include "system/xio.h"
14 
16 #include <petscmat.h>
17 
18 #include "io/output_time.hh"
19 #include "tools/time_governor.hh"
20 #include "system/sys_vector.hh"
21 #include "coupling/equation.hh"
22 #include "transport/transport.h"
23 #include "mesh/mesh.h"
24 #include "flow/old_bcd.hh"
25 
29 #include "reaction/sorption.hh"
31 
33 
34 #include "la/distribution.hh"
35 #include "input/input_type.hh"
36 #include "input/accessors.hh"
37 
38 using namespace Input::Type;
39 
41  = AbstractRecord("Transport", "Secondary equation for transport of substances.")
43  "Time governor setting for the secondary equation.")
45  "Settings for computing balance.")
47  "Parameters of output stream.");
48 
49 
51  = Record("TransportOutput", "Output setting for transport equations.")
53  "Parameters of output stream.");
54 
55 
57  = Record("TransportOperatorSplitting",
58  "Explicit FVM transport (no diffusion)\n"
59  "coupled with reaction and adsorption model (ODE per element)\n"
60  " via operator splitting.")
63  "Specification of transported substances.")
64  // input data
66  "Reaction model involved in transport.")
67 
68  .declare_key("input_fields", Array(
69  ConvectionTransport::EqData().make_field_descriptor_type("TransportOperatorSplitting")
70  .declare_key(OldBcdInput::transport_old_bcd_file_key(), IT::FileName::input(), "File with mesh dependent boundary conditions (obsolete).")
71  ), IT::Default::obligatory(), "")
73  Default("conc"),
74  "List of fields to write to output file.");
75 
76 
77 
78 
79 
80 
81 
83 {
84 
85  ADD_FIELD(porosity, "Mobile porosity", "1");
86  porosity.units( UnitSI::dimensionless() ).flags_add(in_time_term & in_main_matrix & in_rhs);
87 
88  ADD_FIELD(cross_section, "");
89  cross_section.flags( FieldFlag::input_copy ).flags_add(in_time_term & in_main_matrix & in_rhs);
90 
91  ADD_FIELD(sources_density, "Density of concentration sources.", "0");
92  sources_density.units( UnitSI().kg().m(-3).s(-1) )
93  .flags_add(in_rhs);
94 
95  ADD_FIELD(sources_sigma, "Concentration flux.", "0");
96  sources_sigma.units( UnitSI().s(-1) )
97  .flags_add(in_main_matrix & in_rhs);
98 
99  ADD_FIELD(sources_conc, "Concentration sources threshold.", "0");
100  sources_conc.units( UnitSI().kg().m(-3) )
101  .flags_add(in_rhs);
102 }
103 
104 
106 : AdvectionProcessBase(mesh, in_rec ),
107  mh_dh(nullptr)
108 {
109 }
110 
112 {
113 }
114 
115 
116 
117 
118 
119 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
120 
121 
122 
124 : TransportBase(init_mesh, in_rec),
125  convection(NULL),
126  reaction(nullptr),
127  Semchem_reactions(NULL)
128 {
129  START_TIMER("TransportOperatorSpliting");
130 
131  Distribution *el_distribution;
132  int *el_4_loc;
133 
134  // Initialize list of substances.
135  substances_.initialize(in_rec.val<Input::Array>("substances"));
137 
138  convection = new ConvectionTransport(*mesh_, in_rec);
139  this->eq_data_ = &(convection->data());
140 
141  time_ = new TimeGovernor(in_rec.val<Input::Record>("time"), convection->mark_type() );
142 
143 
144  convection->get_par_info(el_4_loc, el_distribution);
145  Input::Iterator<Input::AbstractRecord> reactions_it = in_rec.find<Input::AbstractRecord>("reaction_term");
146  if ( reactions_it ) {
147  if (reactions_it->type() == FirstOrderReaction::input_type ) {
148  reaction = new FirstOrderReaction(init_mesh, *reactions_it);
149  } else
150  if (reactions_it->type() == RadioactiveDecay::input_type) {
151  reaction = new RadioactiveDecay(init_mesh, *reactions_it);
152  } else
153  if (reactions_it->type() == SorptionSimple::input_type ) {
154  reaction = new SorptionSimple(init_mesh, *reactions_it);
155  } else
156  if (reactions_it->type() == DualPorosity::input_type ) {
157  reaction = new DualPorosity(init_mesh, *reactions_it);
158  } else
159  if (reactions_it->type() == Semchem_interface::input_type ) {
160 // Semchem_reactions = new Semchem_interface(0.0, mesh_, n_subst_, false); //false instead of convection->get_dual_porosity
161 // Semchem_reactions->set_el_4_loc(el_4_loc);
162 // //Semchem works with phases 0-3; this is not supported no more!
163 // semchem_conc_ptr = new double**[1];
164 // semchem_conc_ptr[0] = convection->get_concentration_matrix();
165 // Semchem_reactions->set_concentration_matrix(semchem_conc_ptr, el_distribution, el_4_loc);
166  THROW( ReactionTerm::ExcWrongDescendantModel()
167  << ReactionTerm::EI_Model((*reactions_it).type().type_name())
168  << EI_Message("This model is not currently supported!")
169  << (*reactions_it).ei_address());
170 
171  } else {
172  //This point cannot be reached. The TYPE_selection will throw an error first.
173  THROW( ExcMessage()
174  << EI_Message("Descending model type selection failed (SHOULD NEVER HAPPEN).")
175  << (*reactions_it).ei_address());
176  }
177 
180  el_distribution, el_4_loc, convection->get_row_4_el())
181  .output_stream(*(convection->output_stream()))
183 
184  reaction->initialize();
185 
186  } else {
187  reaction = nullptr;
188  Semchem_reactions = nullptr;
189  }
190 
191  //coupling - passing fields
192  if(reaction)
193  if( typeid(*reaction) == typeid(SorptionSimple) ||
194  typeid(*reaction) == typeid(DualPorosity)
195  )
196  {
197  reaction->data().set_field("porosity", convection->data()["porosity"]);
198  }
199 
200  // initialization of balance object
201  Input::Iterator<Input::Record> it = in_rec.find<Input::Record>("balance");
202  if (it->val<bool>("balance_on"))
203  {
204 // convection->get_par_info(el_4_loc, el_distribution);
205 
206  balance_ = boost::make_shared<Balance>("mass", mesh_, el_distribution, el_4_loc, *it);
207 
209 
210  balance_->allocate(el_distribution->lsize(), 1);
211  }
212 }
213 
215 {
216  //delete field_output;
217  delete convection;
218  if (reaction) delete reaction;
220  delete time_;
221 }
222 
223 
224 
225 
227 
228 
229  START_TIMER("TOS-output data");
230 
231  time_->view("TOS"); //show time governor
233  if(reaction) reaction->output_data(); // do not perform write_time_frame
235 
236  if (balance_ != nullptr && time_->is_current( time_->marks().type_output() ))
237  {
238  START_TIMER("TOS-balance");
240  balance_->output(time_->t());
241  END_TIMER("TOS-balance");
242  }
243 
244  END_TIMER("TOS-output data");
245 }
246 
247 
249 {
250 
254  if (balance_ != nullptr)
255  {
256  balance_->units(
260  balance_->output(time_->t());
261  }
262 
263 }
264 
265 
266 
268 
269  vector<double> source(n_substances()), region_mass(mesh_->region_db().bulk_size());
270 
271  time_->next_time();
272 
275 
276  START_TIMER("TOS-one step");
277  int steps=0;
278  while ( convection->time().step().lt(time_->t()) )
279  {
280  steps++;
281  // one internal step
283 
284  if (balance_ != nullptr && balance_->cumulative())
285  {
286  START_TIMER("TOS-balance");
287 
288  // save mass after transport step
289  for (unsigned int sbi=0; sbi<n_substances(); sbi++)
290  {
291  balance_->calculate_mass(convection->get_subst_idx()[sbi], convection->get_concentration_vector()[sbi], region_mass);
292  source[sbi] = 0;
293  for (unsigned int ri=0; ri<mesh_->region_db().bulk_size(); ri++)
294  source[sbi] -= region_mass[ri];
295  }
296 
298 
299  END_TIMER("TOS-balance");
300  }
301 
304 
305  if (balance_ != nullptr && balance_->cumulative())
306  {
307  START_TIMER("TOS-balance");
308 
309  for (unsigned int sbi=0; sbi<n_substances(); sbi++)
310  {
311  // compute mass difference due to reactions
312  balance_->calculate_mass(convection->get_subst_idx()[sbi], convection->get_concentration_vector()[sbi], region_mass);
313  for (unsigned int ri=0; ri<mesh_->region_db().bulk_size(); ri++)
314  source[sbi] += region_mass[ri];
315 
316  // update balance of sources due to reactions
317  balance_->add_cumulative_source(sbi, source[sbi]);
318  }
319 
320  END_TIMER("TOS-balance");
321  }
322  }
323 
324  xprintf( MsgLog, " CONVECTION: steps: %d\n",steps);
325 }
326 
327 
328 
329 
330 
332 {
333  mh_dh = &dh;
335 };
336 
337 
338 
339 
340 
341 
342 
FieldSet & data()
Definition: equation.hh:188
virtual void zero_time_step()
Definition: equation.hh:97
FieldSet * eq_data_
Definition: equation.hh:227
Abstract base class for equation clasess.
void update_solution() override
Definition: transport.cc:495
Accessor to input data conforming to declared Array.
Definition: accessors.hh:558
static Input::Type::AbstractRecord input_type
Common specification of the input record for secondary equations.
virtual void output_data(void)
Output method.
static Input::Type::Record input_type
The specification of output stream.
Definition: output_time.hh:57
bool lt(double other_time) const
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
unsigned int bulk_size() const
Definition: region.cc:252
virtual void initialize()
Initialize fields.
Definition: equation.hh:114
void set_balance_object(boost::shared_ptr< Balance > balance)
Definition: transport.h:149
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:39
MultiField< 3, FieldValue< 3 >::Scalar > conc_mobile
Calculated concentrations in the mobile zone.
Definition: transport.h:103
virtual void set_velocity_field(const MH_DofHandler &dh) override
static Input::Type::Record input_type
Main balance input record type.
void next_time()
Proceed to the next time according to current estimated time step.
Vec * get_concentration_vector()
Definition: transport.h:188
TimeMark::Type type_output()
Definition: time_marks.hh:203
static Default obligatory()
Definition: type_record.hh:89
???
void initialize(const Input::Array &in_array)
Read from input array.
Definition: substance.cc:68
void update_solution(void)
const MH_DofHandler * mh_dh
Definition: mesh.h:109
Iterator< Ret > find(const string &key) const
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:197
bool is_current(const TimeMark::Type &mask) const
Field< 3, FieldValue< 3 >::Scalar > porosity
Mobile porosity.
const RegionDB & region_db() const
Definition: mesh.h:155
static Input::Type::Record input_type
Input record for class FirstOrderReaction.
void calculate_instant_balance()
Definition: transport.cc:792
const TimeStep & step(int index=-1) const
virtual void set_velocity_field(const MH_DofHandler &dh) override
double t() const
void get_par_info(int *&el_4_loc, Distribution *&el_ds)
Definition: transport.cc:748
#define ADD_FIELD(name,...)
Definition: field_set.hh:260
I/O functions with filename storing, able to track current line in opened file. All standard stdio fu...
Basic time management functionality for unsteady (and steady) solvers (class Equation).
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
void zero_time_step() override
Definition: transport.cc:464
unsigned int size() const
Definition: substance.hh:99
static TimeMarks & marks()
Definition: system.hh:72
Basic time management class.
Class for declaration of inputs sequences.
Definition: type_base.hh:239
Specification of transport model interface.
double estimate_dt() const
Estimate choice of next time step according to actual setting of constraints.
OutputTime * output_stream_
Definition: transport.h:276
void view(const char *name="") const
static Input::Type::AbstractRecord input_type
static Default optional()
Definition: type_record.hh:102
static Input::Type::Record input_type
static FileName input()
Definition: type_base.hh:464
static constexpr Mask input_copy
A field that is input of its equation and can not read from input, thus must be set by copy...
Definition: field_flag.hh:29
Class implements the radioactive decay chain.
Accessor to the data with type Type::Record.
Definition: accessors.hh:327
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:100
#define START_TIMER(tag)
Starts a timer with specified tag.
Class for declaration of polymorphic Record.
Definition: type_record.hh:487
Mesh * mesh_
Definition: equation.hh:218
void set_field(const std::string &dest_field_name, FieldCommon &source)
Definition: field_set.cc:101
boost::shared_ptr< Balance > balance_
(new) object for calculation and writing the mass balance to file.
static Input::Type::Record input_type
unsigned int n_subst_
Number of transported substances.
static Input::Type::Record input_type
AbstractRecord & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:466
static Input::Type::Record input_type_output_record
static string transport_old_bcd_file_key()
Definition: old_bcd.hh:58
Class representing dual porosity model in transport.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:448
virtual void set_time_governor(TimeGovernor &time)
Definition: equation.cc:80
void write_time_frame()
Definition: output_time.cc:215
Support classes for parallel programing.
void output_data() override
Write computed fields.
virtual void update_solution()
Definition: equation.hh:105
static Input::Type::Record input_type
Definition: sorption.hh:27
static Input::Type::Selection output_selection
Definition: transport.h:85
SubstanceList substances_
Transported substances.
TimeGovernor const & time()
Definition: equation.hh:143
Vector classes to support both Iterator, index and Id access and creating co-located vectors...
virtual void output_data() override
Write computed fields.
Definition: transport.cc:822
void set_target_time(double target_time)
Definition: transport.cc:579
void calculate_cumulative_balance()
Definition: transport.cc:764
OutputTime * output_stream()
Definition: transport.h:185
#define END_TIMER(tag)
Ends a timer with specified tag.
TimeMark::Type mark_type()
Definition: equation.hh:179
static Input::Type::Record input_type
Input record for class RadioactiveDecay.
const vector< unsigned int > & get_subst_idx()
Definition: transport.h:155
TransportBase(Mesh &mesh, const Input::Record in_rec)
unsigned int n_substances() override
Returns number of trnasported substances.
Simple sorption model without dual porosity.
Definition: sorption.hh:24
Record type proxy class.
Definition: type_record.hh:169
Class implements the linear reactions.
static Input::Type::Record input_type
Declare input record type for the equation TransportOperatorSplittiong.
double ** get_concentration_matrix()
Definition: transport.cc:744
Class for representation SI units of Fields.
Definition: unit_si.hh:31
static Input::Type::Record input_type
Input type for a substance.
Definition: substance.hh:62
UnitSI & md(int exp=-1)
Method sets value of exponent for m^{-d}, where d is dimension of region.
Definition: unit_si.cc:91
static UnitSI & dimensionless()
Returns dimensionless unit.
Definition: unit_si.cc:44
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:34
ReactionTerm & concentration_matrix(double **concentration, Distribution *conc_distr, int *el_4_loc, int *row_4_el)
ReactionTerm & substances(SubstanceList &substances)
Sets the names of substances considered in transport.
TransportOperatorSplitting(Mesh &init_mesh, const Input::Record &in_rec)
Constructor.
TimeGovernor * time_
Definition: equation.hh:219
virtual ~TransportOperatorSplitting()
Destructor.
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:430