Flow123d  release_1.8.2-1603-g0109a2b
hc_explicit_sequential.cc
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 hc_explicit_sequential.cc
15  * @brief
16  * @author Jan Brezina
17  */
18 
21 //#include "flow/darcy_flow_mh_output.hh"
22 // TODO:
23 // After having general default values:
24 // make TransportNoting default for AdvectionProcessBase abstract
25 // use default "{}" for secondary equation.
26 // Then we can remove following include.
28 #include "mesh/mesh.h"
29 #include "mesh/msh_gmshreader.h"
30 #include "system/sys_profiler.hh"
31 #include "input/input_type.hh"
32 #include "input/accessors.hh"
33 
34 
35 FLOW123D_FORCE_LINK_IN_PARENT(transportOperatorSplitting);
36 FLOW123D_FORCE_LINK_IN_PARENT(concentrationTransportModel);
37 FLOW123D_FORCE_LINK_IN_PARENT(convectionTransport);
39 
40 FLOW123D_FORCE_LINK_IN_PARENT(darcy_flow_mh);
41 FLOW123D_FORCE_LINK_IN_PARENT(richards_lmh);
42 
43 
44 namespace it = Input::Type;
45 
47  return it::Abstract("Problem", "The root record of description of particular the problem to solve.")
48  .close();
49 }
50 
51 
53  return it::Record("SequentialCoupling",
54  "Record with data for a general sequential coupling.\n")
56  .declare_key("description",it::String(),
57  "Short description of the solved problem.\n"
58  "Is displayed in the main log, and possibly in other text output files.")
60  "Computational mesh common to all equations.")
62  "Simulation time frame and time step.")
63  .declare_key("primary_equation", DarcyFlowInterface::get_input_type(),
65  "Primary equation, have all data given.")
66  .declare_key("secondary_equation", AdvectionProcessBase::get_input_type(),
67  "The equation that depends (the velocity field) on the result of the primary equation.")
68  .close();
69 }
70 
71 
73 
74 
75 
76 
77 /**
78  * FUNCTION "MAIN" FOR COMPUTING MIXED-HYBRID PROBLEM FOR UNSTEADY SATURATED FLOW
79  */
81 {
82  START_TIMER("HC constructor");
83  using namespace Input;
84 
85  // Read mesh
86  {
87  START_TIMER("HC read mesh");
88  mesh = new Mesh( in_record.val<Record>("mesh") );
89  mesh->init_from_input();
90 
91  //getting description for the Profiler
92  string description;
93  in_record.opt_val<string>("description", description);
94 
96  description,
97  //"Description has to be set in main. by different method.",
98  mesh->n_elements());
99  }
100 
101  // setup primary equation - water flow object
102  AbstractRecord prim_eq = in_record.val<AbstractRecord>("primary_equation");
103  // Need explicit template types here, since reference is used (automatically passing by value)
104  water = prim_eq.factory< DarcyFlowInterface, Mesh &, const Input::Record>(*mesh, prim_eq);
105 
106 
107 
108  // TODO: optionally setup transport objects
109  Iterator<AbstractRecord> it = in_record.find<AbstractRecord>("secondary_equation");
110  if (it) {
111  secondary_eq = (*it).factory< AdvectionProcessBase, Mesh &, const Input::Record >(*mesh, *it);
112 
113  // setup fields
114  secondary_eq->data()["cross_section"]
115  .copy_from(water->data()["cross_section"]);
116  secondary_eq->initialize();
117 
118  } else {
119  secondary_eq = std::make_shared<TransportNothing>(*mesh);
120  }
121 }
122 
123 
124 
125 /**
126  * TODO:
127  * - have support for steady problems in TimeGovernor, make Noting problems steady
128  * - apply splitting of compute_one_step to particular models
129  * - how to set output time marks for steady problems (we need solved time == infinity) but
130  * add no time marks
131  * - allow create steady time governor without time marks (at least in nothing models)
132  * - pass refference to time marks in time governor constructor?
133  */
134 
136 {
137  START_TIMER("HC run simulation");
138  // following should be specified in constructor:
139  // value for velocity interpolation :
140  // theta = 0 velocity from beginning of transport interval (fully explicit method)
141  // theta = 0.5 velocity from center of transport interval ( mimic Crank-Nicholson)
142  // theta = 1.0 velocity from end of transport interval (partialy explicit scheme)
143  const double theta=0.5;
144 
145 
146  double velocity_interpolation_time;
147  bool velocity_changed=true;
148 
149  {
150  START_TIMER("HC water zero time step");
151  water->zero_time_step();
152  }
153 
154 
155  // following cycle is designed to support independent time stepping of
156  // both processes. The question is which value of the water field use to compute a transport step.
157  // Meaningful cases are
158  // 1) beginning (fully explicit method)
159  // 2) center ( mimic Crank-Nicholson)
160  // 3) end of the interval (partialy explicit scheme)
161  // However with current implementation of the explicit transport on have to assembly transport matrix for
162  // every new value of the velocity field. So we have to keep same velocity field over some time interval t_dt
163  // which is further split into shorter time intervals ts_dt dictated by the CFL condition.
164  // One can consider t_dt as the transport time step and apply one of the previous three cases.
165  //
166  // The question is how to choose intervals t_dt. That should depend on variability of the velocity field in time.
167  // Currently we simply use t_dt == w_dt.
168 
169  while (! (water->time().is_end() && secondary_eq->time().is_end() ) ) {
170 
171  if (! water->time().is_end()) {
172  double water_dt=water->time().estimate_dt();
173  secondary_eq->set_time_upper_constraint(water_dt, "Time discretisation of flow.");
174  }
175 
176  // in future here could be re-estimation of transport planed time according to
177  // evolution of the velocity field. Consider the case w_dt << t_dt and velocity almost constant in time
178  // which suddenly rise in time 3*w_dt. First we the planed transport time step t_dt could be quite big, but
179  // in time 3*w_dt we can reconsider value of t_dt to better capture changing velocity.
180  velocity_interpolation_time= theta * secondary_eq->planned_time() + (1-theta) * secondary_eq->solved_time();
181 
182  // printing water and transport times every step
183  //xprintf(Msg,"HC_EXPL_SEQ: velocity_interpolation_time: %f, water_time: %f transport time: %f\n",
184  // velocity_interpolation_time, water->time().t(), transport_reaction->time().t());
185 
186  // if transport is off, transport should return infinity solved and planned times so that
187  // only water branch takes the place
188  if (water->solved_time() < velocity_interpolation_time) {
189  // solve water over the nearest transport interval
190  water->update_solution();
191 
192  // here possibly save solution from water for interpolation in time
193 
194  //water->time().view("WATER"); //show water time governor
195 
196  //water->output_data();
197  water->choose_next_time();
198 
199  velocity_changed = true;
200  } else {
201  // having information about velocity field we can perform transport step
202 
203  // here should be interpolation of the velocity at least if the interpolation time
204  // is not close to the solved_time of the water module
205  // for simplicity we use only last velocity field
206  if (velocity_changed) {
207  //DBGMSG("velocity update\n");
208  secondary_eq->set_velocity_field( water->get_mh_dofhandler() );
209  velocity_changed = false;
210  }
211  if (secondary_eq->time().tlevel() == 0) secondary_eq->zero_time_step();
212 
213  secondary_eq->update_solution();
214 
215  //transport_reaction->time().view("TRANSPORT"); //show transport time governor
216 
217  secondary_eq->output_data();
218  }
219 
220  }
221  xprintf(Msg, "End of simulation at time: %f\n", secondary_eq->solved_time());
222 }
223 
224 
226  water.reset();
227  secondary_eq.reset();
228  delete mesh;
229 }
230 
231 
232 
233 
234 //-----------------------------------------------------------------------------
235 // vim: set cindent:
236 //-----------------------------------------------------------------------------
static Input::Type::Abstract & get_input_type()
Definition: system.hh:59
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:578
static const Input::Type::Record & get_input_type()
Definition: mesh.cc:58
static Default obligatory()
The factory function to make an empty default value which is obligatory.
Definition: type_record.hh:99
Definition: mesh.h:99
Iterator< Ret > find(const string &key) const
Abstract & close()
Can be used to close the Abstract for further declarations of keys.
HC_ExplicitSequential(Input::Record in_record)
virtual Record & derive_from(Abstract &parent)
Method to derive new Record from an AbstractRecord parent.
Definition: type_record.cc:193
static Default optional()
The factory function to make an empty default value which is optional.
Definition: type_record.hh:113
bool opt_val(const string &key, Ret &value) const
static Input::Type::Abstract & get_input_type()
Common specification of the input record for secondary equations.
Accessor to the data with type Type::Record.
Definition: accessors.hh:277
const Ret val(const string &key) const
#define xprintf(...)
Definition: system.hh:87
#define START_TIMER(tag)
Starts a timer with specified tag.
Record & declare_key(const string &key, std::shared_ptr< TypeBase > type, const Default &default_value, const string &description, TypeBase::attribute_map key_attributes=TypeBase::attribute_map())
Declares a new key of the Record.
Definition: type_record.cc:459
static Input::Type::Abstract & get_input_type()
const Record & close() const
Close the Record for further declarations of keys.
Definition: type_record.cc:271
Class for declaration of polymorphic Record.
Accessor to the polymorphic input data of a type given by an AbstracRecord object.
Definition: accessors.hh:444
static Profiler * instance()
static const Input::Type::Record & get_input_type()
static const Input::Type::Record & get_input_type()
Record type proxy class.
Definition: type_record.hh:171
const std::shared_ptr< Type > factory(Arguments...arguments) const
FLOW123D_FORCE_LINK_IN_PARENT(transportOperatorSplitting)
Class for declaration of the input data that are in string format.
Definition: type_base.hh:563
void set_task_info(string description, int size)