Flow123d  jenkins-Flow123d-linux-release-multijob-198
semchem_interface.cc
Go to the documentation of this file.
1 //---------------------------------------------------------------------------
2 
4 
5 #include "system/system.hh"
6 #include "system/sys_profiler.hh"
7 #include "io/read_ini.h"
8 
9 #include "semchem/che_semchem.h"
11 #include "mesh/mesh.h"
13 #include "fields/field_values.hh"
14 
15 #define MOBILE 0
16 #define IMMOBILE 1
17 
18 using namespace std;
19 
20 //---------------------------------------------------------------------------
21 // GLOBALNI PROMENNE
22 //---------------------------------------------------------------------------
23 struct TS_prm G_prm;
24 struct TS_lat *P_lat;
25 struct TS_che *P_che;
26 
27 //---------------------------------------------------------------------------
28 namespace it = Input::Type;
29 
30 it::Record Specie::input_type = it::Record("Isotope", "Definition of information about a single isotope.")
32  "Identifier of the isotope.")
34  "Half life parameter.");
35 
36 
37 it::Record General_reaction::input_type = it::Record("Isotope", "Definition of information about a single isotope.")
39  "Identifier of the isotope.")
41  "Half life parameter.");
42 
43 
44 it::Record Semchem_interface::input_type = it::Record("Semchem", "Declares infos valid for all reactions. NOT SUPPORTED!!!.")
46  .declare_key("precision", it::Integer(), it::Default::obligatory(), //(1),
47  "How accurate should the simulation be, decimal places(?).")
48  .declare_key("temperature", it::Double(), it::Default::obligatory(), //(298.0),
49  "Isothermal reaction, thermodynamic temperature.")
50  .declare_key("temp_gf", it::Double(), it::Default::obligatory(), //(298.0),
51  "Thermodynamic parameter.")
52  .declare_key("param_afi", it::Double(), it::Default::obligatory(), //(0.391475),
53  "Thermodynamic parameter.")
54  .declare_key("param_b", it::Double(), it::Default::obligatory(), //(1.2),
55  "Thermodynamic parameter.")
56  .declare_key("epsilon", it::Double(), it::Default::obligatory(), //(1.2),
57  "Thermodynamic parameter.")
58  .declare_key("time_steps", it::Integer(), it::Default::obligatory(), //(10),
59  "Simulation parameter.")
60  .declare_key("slow_kinetic_steps", it::Integer(), it::Default::obligatory(), //(1),
61  "Simulation parameter.");
62 
63 
64 Semchem_interface::Semchem_interface(double timeStep, Mesh * mesh, int nrOfSpecies, bool dualPorosity)
65  :semchem_on(false), dual_porosity_on(false), fw_chem(NULL), mesh_(NULL), cross_section(NULL)
66 {
67 
68  //temporary semchem output file name
69  std::string semchem_output_fname = FilePath("semchem_output.out", FilePath::output_file);
70  xprintf(Msg,"Semchem output file name is %s\n",semchem_output_fname.c_str());
71 
72  this->set_fw_chem(semchem_output_fname); //DOES NOT WORK ((const char*)semchem_output_fname.c_str());
74  if(semchem_on == true) ctiich();
76  set_mesh_(mesh);
78  return;
79 }
80 
82 {
84 }
85 
87  Field<3, FieldValue<3>::Scalar> *por_imm_,
88  Field<3, FieldValue<3>::Scalar> *phi_)
89 {
90  por_m = por_m_;
91  por_imm = por_imm_;
92  phi = phi_;
93 }
94 
95 
97 {
98  if(semchem_on == true)
99  {
100  for (unsigned int loc_el = 0; loc_el < distribution->lsize(); loc_el++)
101  {
102  START_TIMER("semchem-one step");
104  END_TIMER("semchem-one step");
105  }
106  }
107 }
108 
109 //---------------------------------------------------------------------------
110 // FUNKCE NA VYPOCET CHEMIE PRO ELEMENT V TRANSPORTU
111 //---------------------------------------------------------------------------
112 void Semchem_interface::compute_reaction(bool porTyp, ElementIter ppelm, int poradi, double ***conc)
113 {
114  int i;
115  int krok;
116  int poc_krok;
117  double celkova_molalita;
118  char *vystupni_soubor;
119  double **conc_mob_arr = conc[MOBILE];
120  double **conc_immob_arr = conc[IMMOBILE];
121  double pomoc;
122  double el_por_m = por_m->value(ppelm->centre(), ppelm->element_accessor());
123  double el_por_imm = por_imm->value(ppelm->centre(), ppelm->element_accessor());
124  double el_phi = phi->value(ppelm->centre(), ppelm->element_accessor());
125 
126  vystupni_soubor = fw_chem;
127  //==================================================================
128  // ----------- ALOKACE POLE PRO KONCENTRACE Z FLOWA ----------------
129  //==================================================================
130 
131  ASSERT(P_lat != NULL,"\nP_lat NENI ALOKOVANE\n");
132 
133  //==================================================================
134  // ----------------- NEJPRVE PRO MOBILNI PORY ----------------------
135  //==================================================================
136  switch (ppelm->dim()) { //objem se snad na nic nepouzzi:va:
137  case 1 :
138  case 2 :
139  case 3 : pomoc = ppelm->measure() *
140  cross_section->value(ppelm->centre(), ppelm->element_accessor() ) *
141  el_por_m;
142  break;
143  default:
144  pomoc = 1.0;
145  }
146 
147  G_prm.objem = pomoc; //objem * mobilni: porozita
148  G_prm.splocha = (pomoc / el_por_m) * (el_phi) * (1 - el_por_m - el_por_imm);
149  celkova_molalita=0.0;
150  poc_krok=1;
151 
152  //------------PREDANI VSECH INFORMACI Z FLOWA DO SEMCHEMU----------
153  for ( i=0 ; i<(G_prm.pocet_latekvefazi); i++)
154  {
155  P_lat[i].m0 = (double)((conc_mob_arr[i][poradi])) / (P_lat[i].M);
156  celkova_molalita += (P_lat[i].m0);
157  }
158  G_prm.deltaT = time_step/G_prm.cas_kroku; // dosazeni "spravneho" casoveho kroku
159 
160  //-----------------------VYPOCET CHEMIE----------------------------
161  if (celkova_molalita > 1e-16)
162  {
163  for (krok = 1; krok <= G_prm.cas_kroku; krok++)
164  {
165  che_pocitej_soubor(vystupni_soubor, &poc_krok);
166  for (i = 0; i < G_prm.pocet_latekvefazi; i++) {
167  P_lat[i].m0 = P_lat[i].m;
168  }
170  }
171 
172  //------------PREDANI VSECH INFORMACI ZE SEMCHEMU DO FLOWA---------
173  for ( i=0 ; i<G_prm.pocet_latekvefazi; i++)
174  {
175  conc_mob_arr[i][poradi] = (double)(P_lat[i].m0 * P_lat[i].M);
176  }
177  }
178 
179  //==================================================================
180  // ----------------- POTE PRO IMOBILNI PORY ------------------------
181  //==================================================================
182  if(porTyp == true) {
183  switch (ppelm->dim()) { //objem se snad na nic nepouzzi:va:
184  case 1 :
185  case 2 :
186  case 3 : pomoc = ppelm->measure() *
187  cross_section->value(ppelm->centre(), ppelm->element_accessor() ) *
188  el_por_imm;
189  break;
190  default:
191  pomoc = 1.0;
192  }
193  G_prm.objem = pomoc;
194  G_prm.splocha = (pomoc / el_por_imm) * (1 - el_phi) * (1 - el_por_m - el_por_imm);
195  celkova_molalita = 0.0;
196  poc_krok=1;
197 
198  //------------PREDANI VSECH INFORMACI Z FLOWA DO SEMCHEMU----------
199  for ( i=0 ; i<G_prm.pocet_latekvefazi ; i++)
200  {
201  P_lat[i].m0 = (double)(conc_immob_arr[i][poradi] / P_lat[i].M);
202  celkova_molalita += P_lat[i].m0;
203  }
204 
205  //-----------------------VYPOCET CHEMIE----------------------------
206  if (celkova_molalita > 1e-16)
207  {
208  for (krok = 1; krok<=G_prm.cas_kroku; krok++)
209  {
210  che_pocitej_soubor(vystupni_soubor,&poc_krok);
212  }
213 
214  //------------PREDANI VSECH INFORMACI ZE SEMCHEMU DO FLOWA---------
215  for ( i=0 ; i<G_prm.pocet_latekvefazi ; i++)
216  {
217  conc_immob_arr[i][poradi] = (P_lat[i].m0 * P_lat[i].M); //m nebo m0, co?
218  }
219  }
220  }else{
221  ;
222  }
223 }
224 
225 void Semchem_interface::set_timestep(double new_timestep)
226 {
227  this->time_step = new_timestep;
228  return;
229 }
230 
232 {
233  this->semchem_on = OptGetBool("Semchem_module", "Compute_reactions", "no");
234  return;
235 }
236 
238 {
239  this->dual_porosity_on = OptGetBool("Transport", "Dual_porosity", "no");
240  return;
241 }
242 
244 {
245  this->nr_of_elements = nrOfElements;
246  return;
247 }
248 
249 void Semchem_interface::set_concentration_matrix(double ***ConcentrationMatrix, Distribution *conc_distr, int *el_4_loc)
250 {
251  concentration_matrix = ConcentrationMatrix;
252  distribution = conc_distr;
253  return;
254 }
255 
256 void Semchem_interface::set_el_4_loc(int *el_for_loc)
257 {
258  el_4_loc = el_for_loc;
259  return;
260 }
261 
263 {
264  mesh_ = mesh;
265  return;
266 }
267 
268 void Semchem_interface::set_fw_chem(std::string semchem_output_file)
269 {
270  fw_chem = (char*)xmalloc(semchem_output_file.length()+1);
271  strcpy(fw_chem,semchem_output_file.c_str());
272  xprintf(Msg,"Output file for Semchem is %s\n",fw_chem);
273  return;
274 }
double measure() const
Definition: elements.cc:101
#define vystupni_soubor
Definition: che_semchem.cc:8
int pocet_latekvefazi
Definition: che_semchem.h:616
void set_el_4_loc(int *el_for_loc)
Semchem_interface(double timeStep, Mesh *mesh, int nrOfSpecies, bool dualPorosity)
Definition: system.hh:72
void che_presun_poc_p_(void)
struct TS_prm G_prm
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:52
struct TS_lat * P_lat
static Default obligatory()
Definition: type_record.hh:89
???
void compute_reaction(bool porTyp, ElementIter ppelm, int poradi, double ***conc)
int cas_kroku
Definition: che_semchem.h:632
void update_solution(void)
bool OptGetBool(const char *section, const char *key, const char *defval)
Definition: read_ini.cc:279
Definition: mesh.h:109
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:197
Distribution * distribution
double deltaT
Definition: che_semchem.h:629
void set_nr_of_elements(int nrOfElements)
void set_cross_section(Field< 3, FieldValue< 3 >::Scalar > *cross_section)
Sets pointer to data of other equations.
void che_pocitej_soubor(char *soubor, int *poc_krok)
Class for declaration of the integral input data.
Definition: type_base.hh:355
static Input::Type::AbstractRecord input_type
unsigned int dim() const
double M
Definition: che_semchem.h:644
static Input::Type::Record input_type
#define MOBILE
unsigned int n_elements() const
Definition: mesh.h:141
static Input::Type::Record input_type
#define ASSERT(...)
Definition: global_defs.h:121
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:392
#define IMMOBILE
Field< 3, FieldValue< 3 >::Scalar > * por_imm
double splocha
Definition: che_semchem.h:631
#define xprintf(...)
Definition: system.hh:100
void set_dual_porosity(void)
#define START_TIMER(tag)
Starts a timer with specified tag.
Field< 3, FieldValue< 3 >::Scalar > * phi
struct TS_che * P_che
void set_mesh_(Mesh *mesh)
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:312
static Input::Type::Record input_type
double *** concentration_matrix
void * xmalloc(size_t size)
Memory allocation with checking.
Definition: system.cc:209
void set_sorption_fields(Field< 3, FieldValue< 3 >::Scalar > *por_m_, Field< 3, FieldValue< 3 >::Scalar > *por_imm_, Field< 3, FieldValue< 3 >::Scalar > *phi_)
void set_timestep(double new_timestep)
Dedicated class for storing path to input and output files.
Definition: file_path.hh:32
double m
Definition: che_semchem.h:643
arma::vec3 centre() const
Definition: elements.cc:132
void set_fw_chem(std::string semchem_output_file)
Field< 3, FieldValue< 3 >::Scalar > * por_m
pointers to sorption fields from transport
void set_chemistry_computation(void)
#define END_TIMER(tag)
Ends a timer with specified tag.
ElementAccessor< 3 > element_accessor() const
Gets ElementAccessor of this element.
Definition: elements.cc:160
void set_concentration_matrix(double ***ConcentrationsMatrix, Distribution *conc_distr, int *el_4_loc)
void ctiich(void)
Definition: che_read.cc:560
Record type proxy class.
Definition: type_record.hh:169
double objem
Definition: che_semchem.h:630
double m0
Definition: che_semchem.h:642
ElementVector element
Vector of elements of the mesh.
Definition: mesh.h:205
Field< 3, FieldValue< 3 >::Scalar > * cross_section
unsigned int lsize(int proc) const
get local size
Record & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:430