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