Flow123d
semchem_interface.cc
Go to the documentation of this file.
1 //---------------------------------------------------------------------------
2 
3 #include "reaction/reaction.hh"
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 "transport/transport.h"
12 #include "mesh/mesh.h"
13 #include "fields/field_base.hh"
14 #include "fields/field_values.hh"
15 
16 #define MOBILE 0
17 #define IMMOBILE 1
18 
19 using namespace std;
20 
21 //---------------------------------------------------------------------------
22 // GLOBALNI PROMENNE
23 //---------------------------------------------------------------------------
24 struct TS_prm G_prm;
25 struct TS_lat *P_lat;
26 struct TS_che *P_che;
27 
28 //---------------------------------------------------------------------------
29 namespace it = Input::Type;
30 
31 it::Record Specie::input_type = it::Record("Isotope", "Definition of information about a single isotope.")
33  "Identifier of the isotope.")
35  "Half life parameter.");
36  /*rec.declare_key("next", Array(Integer()), Default(0),
37  "Identifiers of childern in decay chain.");
38  rec.declare_key("bifurcation", Array(Double), Default(0),
39  "Fractions of division decay chain into branches.");
40  rec.declare_key("kinetic constant", Double(), Default(1.0),
41  "Kinetic conxtant appropriate to described first order reaction.");*/
42 
43 
44 it::Record General_reaction::input_type = it::Record("Isotope", "Definition of information about a single isotope.")
46  //rec.declare_key("general_reaction", Array( Linear_reaction::get_one_decay_substep() ), Default::optional(),
47  // "Description of general chemical reactions.");
49  "Identifier of the isotope.")
51  "Half life parameter.");
52  /*rec.declare_key("next", Array(Integer()), Default(0),
53  "Identifiers of childern in decay chain.");
54  rec.declare_key("bifurcation", Array(Double), Default(0),
55  "Fractions of division decay chain into branches.");
56  rec.declare_key("kinetic constant", Double(), Default(1.0),
57  "Kinetic conxtant appropriate to described first order reaction.");*/
58 
59 
60 it::AbstractRecord Semchem_interface::input_type = it::AbstractRecord("Semchem_module", "Declares infos valid for all reactions.")
61  .declare_key("precision", it::Integer(), it::Default::obligatory(), //(1),
62  "How accurate should the simulation be, decimal places(?).")
63  .declare_key("temperature", it::Double(), it::Default::obligatory(), //(298.0),
64  "Isothermal reaction, thermodynamic temperature.")
65  .declare_key("temp_gf", it::Double(), it::Default::obligatory(), //(298.0),
66  "Thermodynamic parameter.")
67  .declare_key("param_afi", it::Double(), it::Default::obligatory(), //(0.391475),
68  "Thermodynamic parameter.")
69  .declare_key("param_b", it::Double(), it::Default::obligatory(), //(1.2),
70  "Thermodynamic parameter.")
71  .declare_key("epsilon", it::Double(), it::Default::obligatory(), //(1.2),
72  "Thermodynamic parameter.")
73  .declare_key("time_steps", it::Integer(), it::Default::obligatory(), //(10),
74  "Simulation parameter.")
75  .declare_key("slow_kinetic_steps", it::Integer(), it::Default::obligatory(), //(1),
76  "Simulation parameter.");
77 
78 
79 Semchem_interface::Semchem_interface(double timeStep, Mesh * mesh, int nrOfSpecies, bool dualPorosity)
80  :semchem_on(false), dual_porosity_on(false), fw_chem(NULL), mesh_(NULL), cross_section(cross_section)
81 {
82 
83  //temporary semchem output file name
84  std::string semchem_output_fname = FilePath("semchem_output.out", FilePath::output_file);
85  xprintf(Msg,"Semchem output file name is %s\n",semchem_output_fname.c_str());
86 
87  //char *Semchem_output_file;
88  //= semchem_output_fname.c_str();
89  //Semchem_output_file = (char *)xmalloc(sizeof(char)*(semchem_output_fname.length() + 1));
90  //sprintf(Semchem_output_file,"%s",semchem_output_fname.c_str());
91  //strcpy(Semchem_output_file,semchem_output_fname.c_str());
92  //Semchem_output_file[semchem_output_fname.length()] = "\0";
93 
94  this->set_fw_chem(semchem_output_fname); //DOES NOT WORK ((const char*)semchem_output_fname.c_str());
96  if(semchem_on == true) ctiich();
98  set_mesh_(mesh);
100  return;
101 }
102 
104 {
106 }
107 
109  Field<3, FieldValue<3>::Scalar> *por_imm_,
110  Field<3, FieldValue<3>::Scalar> *phi_)
111 {
112  por_m = por_m_;
113  por_imm = por_imm_;
114  phi = phi_;
115 }
116 
117 
118 /*Semchem_interface::~Semchem_interface(void)
119 {
120  if(fw_chem != NULL)
121  {
122  free(fw_chem);
123  fw_chem = NULL;
124  }
125  return;
126 }*/
127 
129 {
130  if(semchem_on == true)
131  {
132  for (int loc_el = 0; loc_el < distribution->lsize(); loc_el++)
133  {
134  START_TIMER("semchem-one step");
136  END_TIMER("semchem-one step");
137  }
138  }
139 }
140 
141 //---------------------------------------------------------------------------
142 // FUNKCE NA VYPOCET CHEMIE PRO ELEMENT V TRANSPORTU
143 //---------------------------------------------------------------------------
144 //void Semchem_interface::compute_reaction(bool porTyp, ElementIter ppelm, int poradi, double **conc_mob_arr, double **conc_immob_arr)
145 void Semchem_interface::compute_reaction(bool porTyp, ElementIter ppelm, int poradi, double ***conc)
146 {
147  //FILE *fw, *stream, *fr;
148  int i; //, j, poradi;
149  int krok;
150  int poc_krok;
151  double celkova_molalita;
152  char *vystupni_soubor; //[] = "./output/semchem_output.txt";
153  double **conc_mob_arr = conc[MOBILE];
154  double **conc_immob_arr = conc[IMMOBILE];
155  double pomoc, n;
156  double el_por_m = por_m->value(ppelm->centre(), ppelm->element_accessor());
157  double el_por_imm = por_imm->value(ppelm->centre(), ppelm->element_accessor());
158  double el_phi = phi->value(ppelm->centre(), ppelm->element_accessor());
159 
160  vystupni_soubor = fw_chem;
161  //==================================================================
162  // ----------- ALOKACE POLE PRO KONCENTRACE Z FLOWA ----------------
163  //==================================================================
164 
165  ASSERT(P_lat != NULL,"\nP_lat NENI ALOKOVANE\n");
166 
167  //==================================================================
168  // ----------------- NEJPRVE PRO MOBILNI PORY ----------------------
169  //==================================================================
170  n = (el_por_m) / (1 - el_por_m); //asi S/V jako zze splocha
171 
172  switch (ppelm->dim()) { //objem se snad na nic nepouzzi:va:
173  case 1 :
174  case 2 :
175  case 3 : pomoc = ppelm->measure() *
176  cross_section->value(ppelm->centre(), ppelm->element_accessor() ) *
177  el_por_m;
178  break;
179  default:
180  pomoc = 1.0;
181  }
182 
183  G_prm.objem = pomoc; //objem * mobilni: porozita
184  G_prm.splocha = (pomoc / el_por_m) * (el_phi) * (1 - el_por_m - el_por_imm);
185  celkova_molalita=0.0;
186  poc_krok=1;
187 
188  //------------PREDANI VSECH INFORMACI Z FLOWA DO SEMCHEMU----------
189  for ( i=0 ; i<(G_prm.pocet_latekvefazi); i++)
190  {
191  P_lat[i].m0 = (double)((conc_mob_arr[i][poradi])) / (P_lat[i].M);
192  celkova_molalita += (P_lat[i].m0);
193  }
194  G_prm.deltaT = time_step/G_prm.cas_kroku; // dosazeni "spravneho" casoveho kroku
195 
196  //-----------------------VYPOCET CHEMIE----------------------------
197  if (celkova_molalita > 1e-16)
198  {
199  for (krok = 1; krok <= G_prm.cas_kroku; krok++)
200  {
201  che_pocitej_soubor(vystupni_soubor, &poc_krok);
202  for (i = 0; i < G_prm.pocet_latekvefazi; i++) {
203  P_lat[i].m0 = P_lat[i].m;
204  }
206  }
207 
208  //------------PREDANI VSECH INFORMACI ZE SEMCHEMU DO FLOWA---------
209  for ( i=0 ; i<G_prm.pocet_latekvefazi; i++)
210  {
211  conc_mob_arr[i][poradi] = (double)(P_lat[i].m0 * P_lat[i].M);
212  }
213  }
214 
215  //==================================================================
216  // ----------------- POTE PRO IMOBILNI PORY ------------------------
217  //==================================================================
218  if(porTyp == true) {
219  switch (ppelm->dim()) { //objem se snad na nic nepouzzi:va:
220  case 1 :
221  case 2 :
222  case 3 : pomoc = ppelm->measure() *
223  cross_section->value(ppelm->centre(), ppelm->element_accessor() ) *
224  el_por_imm;
225  break;
226  default:
227  pomoc = 1.0;
228  }
229  G_prm.objem = pomoc;
230  G_prm.splocha = (pomoc / el_por_imm) * (1 - el_phi) * (1 - el_por_m - el_por_imm);
231  celkova_molalita = 0.0;
232  poc_krok=1;
233 
234  //------------PREDANI VSECH INFORMACI Z FLOWA DO SEMCHEMU----------
235  for ( i=0 ; i<G_prm.pocet_latekvefazi ; i++)
236  {
237  P_lat[i].m0 = (double)(conc_immob_arr[i][poradi] / P_lat[i].M);
238  celkova_molalita += P_lat[i].m0;
239  }
240 
241  //-----------------------VYPOCET CHEMIE----------------------------
242  if (celkova_molalita > 1e-16)
243  {
244  //if (G_prm.vypisy==1) che_nadpis__soubor(fw_chem);
245 
246  for (krok = 1; krok<=G_prm.cas_kroku; krok++)
247  {
248  che_pocitej_soubor(vystupni_soubor,&poc_krok);
250  }
251 
252  //------------PREDANI VSECH INFORMACI ZE SEMCHEMU DO FLOWA---------
253  for ( i=0 ; i<G_prm.pocet_latekvefazi ; i++)
254  {
255  conc_immob_arr[i][poradi] = (P_lat[i].m0 * P_lat[i].M); //m nebo m0, co?
256  }
257  }
258  }else{
259  ;
260  }
261 }
262 
263 void Semchem_interface::set_timestep(double new_timestep)
264 {
265  this->time_step = new_timestep;
266  return;
267 }
268 
270 {
271  this->semchem_on = OptGetBool("Semchem_module", "Compute_reactions", "no");
272  return;
273 }
274 
276 {
277  this->dual_porosity_on = OptGetBool("Transport", "Dual_porosity", "no");
278  return;
279 }
280 
282 {
283  this->nr_of_elements = nrOfElements;
284  return;
285 }
286 
287 void Semchem_interface::set_concentration_matrix(double ***ConcentrationMatrix, Distribution *conc_distr, int *el_4_loc)
288 {
289  concentration_matrix = ConcentrationMatrix;
290  distribution = conc_distr;
291  return;
292 }
293 
294 void Semchem_interface::set_el_4_loc(int *el_for_loc)
295 {
296  el_4_loc = el_for_loc;
297  return;
298 }
299 
301 {
302  mesh_ = mesh;
303  return;
304 }
305 
306 void Semchem_interface::set_fw_chem(std::string semchem_output_file) //(const char* semchem_output_file)
307 {
308  //fw_chem = (char*)xmalloc(sizeof((semchem_output_file)/sizeof(char)+1)*sizeof(char));
309  fw_chem = (char*)xmalloc(semchem_output_file.length()+1);
310  strcpy(fw_chem,semchem_output_file.c_str());
311  xprintf(Msg,"Output file for Semchem is %s\n",fw_chem);
312  return;
313 }