Flow123d  jenkins-Flow123d-windows32-release-multijob-28
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"
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(NULL)
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 (unsigned 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;
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  switch (ppelm->dim()) { //objem se snad na nic nepouzzi:va:
171  case 1 :
172  case 2 :
173  case 3 : pomoc = ppelm->measure() *
174  cross_section->value(ppelm->centre(), ppelm->element_accessor() ) *
175  el_por_m;
176  break;
177  default:
178  pomoc = 1.0;
179  }
180 
181  G_prm.objem = pomoc; //objem * mobilni: porozita
182  G_prm.splocha = (pomoc / el_por_m) * (el_phi) * (1 - el_por_m - el_por_imm);
183  celkova_molalita=0.0;
184  poc_krok=1;
185 
186  //------------PREDANI VSECH INFORMACI Z FLOWA DO SEMCHEMU----------
187  for ( i=0 ; i<(G_prm.pocet_latekvefazi); i++)
188  {
189  P_lat[i].m0 = (double)((conc_mob_arr[i][poradi])) / (P_lat[i].M);
190  celkova_molalita += (P_lat[i].m0);
191  }
192  G_prm.deltaT = time_step/G_prm.cas_kroku; // dosazeni "spravneho" casoveho kroku
193 
194  //-----------------------VYPOCET CHEMIE----------------------------
195  if (celkova_molalita > 1e-16)
196  {
197  for (krok = 1; krok <= G_prm.cas_kroku; krok++)
198  {
199  che_pocitej_soubor(vystupni_soubor, &poc_krok);
200  for (i = 0; i < G_prm.pocet_latekvefazi; i++) {
201  P_lat[i].m0 = P_lat[i].m;
202  }
204  }
205 
206  //------------PREDANI VSECH INFORMACI ZE SEMCHEMU DO FLOWA---------
207  for ( i=0 ; i<G_prm.pocet_latekvefazi; i++)
208  {
209  conc_mob_arr[i][poradi] = (double)(P_lat[i].m0 * P_lat[i].M);
210  }
211  }
212 
213  //==================================================================
214  // ----------------- POTE PRO IMOBILNI PORY ------------------------
215  //==================================================================
216  if(porTyp == true) {
217  switch (ppelm->dim()) { //objem se snad na nic nepouzzi:va:
218  case 1 :
219  case 2 :
220  case 3 : pomoc = ppelm->measure() *
221  cross_section->value(ppelm->centre(), ppelm->element_accessor() ) *
222  el_por_imm;
223  break;
224  default:
225  pomoc = 1.0;
226  }
227  G_prm.objem = pomoc;
228  G_prm.splocha = (pomoc / el_por_imm) * (1 - el_phi) * (1 - el_por_m - el_por_imm);
229  celkova_molalita = 0.0;
230  poc_krok=1;
231 
232  //------------PREDANI VSECH INFORMACI Z FLOWA DO SEMCHEMU----------
233  for ( i=0 ; i<G_prm.pocet_latekvefazi ; i++)
234  {
235  P_lat[i].m0 = (double)(conc_immob_arr[i][poradi] / P_lat[i].M);
236  celkova_molalita += P_lat[i].m0;
237  }
238 
239  //-----------------------VYPOCET CHEMIE----------------------------
240  if (celkova_molalita > 1e-16)
241  {
242  //if (G_prm.vypisy==1) che_nadpis__soubor(fw_chem);
243 
244  for (krok = 1; krok<=G_prm.cas_kroku; krok++)
245  {
246  che_pocitej_soubor(vystupni_soubor,&poc_krok);
248  }
249 
250  //------------PREDANI VSECH INFORMACI ZE SEMCHEMU DO FLOWA---------
251  for ( i=0 ; i<G_prm.pocet_latekvefazi ; i++)
252  {
253  conc_immob_arr[i][poradi] = (P_lat[i].m0 * P_lat[i].M); //m nebo m0, co?
254  }
255  }
256  }else{
257  ;
258  }
259 }
260 
261 void Semchem_interface::set_timestep(double new_timestep)
262 {
263  this->time_step = new_timestep;
264  return;
265 }
266 
268 {
269  this->semchem_on = OptGetBool("Semchem_module", "Compute_reactions", "no");
270  return;
271 }
272 
274 {
275  this->dual_porosity_on = OptGetBool("Transport", "Dual_porosity", "no");
276  return;
277 }
278 
280 {
281  this->nr_of_elements = nrOfElements;
282  return;
283 }
284 
285 void Semchem_interface::set_concentration_matrix(double ***ConcentrationMatrix, Distribution *conc_distr, int *el_4_loc)
286 {
287  concentration_matrix = ConcentrationMatrix;
288  distribution = conc_distr;
289  return;
290 }
291 
292 void Semchem_interface::set_el_4_loc(int *el_for_loc)
293 {
294  el_4_loc = el_for_loc;
295  return;
296 }
297 
299 {
300  mesh_ = mesh;
301  return;
302 }
303 
304 void Semchem_interface::set_fw_chem(std::string semchem_output_file) //(const char* semchem_output_file)
305 {
306  //fw_chem = (char*)xmalloc(sizeof((semchem_output_file)/sizeof(char)+1)*sizeof(char));
307  fw_chem = (char*)xmalloc(semchem_output_file.length()+1);
308  strcpy(fw_chem,semchem_output_file.c_str());
309  xprintf(Msg,"Output file for Semchem is %s\n",fw_chem);
310  return;
311 }
double measure() const
Definition: elements.cc:107
#define vystupni_soubor
Definition: che_semchem.cc:10
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:75
void che_presun_poc_p_(void)
Class template representing a field with values dependent on: point, element, and region...
Definition: field.hh:48
static Default obligatory()
Definition: type_record.hh:87
???
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:279
Definition: mesh.h:108
Record & derive_from(AbstractRecord &parent)
Definition: type_record.cc:172
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:341
static Input::Type::AbstractRecord input_type
Definition: reaction.hh:24
unsigned int dim() const
double M
Definition: che_semchem.h:663
#define MOBILE
unsigned int n_elements() const
Definition: mesh.h:137
static Input::Type::Record input_type
#define ASSERT(...)
Definition: global_defs.h:120
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:376
#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:104
void set_dual_porosity(void)
#define START_TIMER(tag)
Starts a timer with specified tag.
Field< 3, FieldValue< 3 >::Scalar > * phi
Class for declaration of polymorphic Record.
Definition: type_record.hh:467
void set_mesh_(Mesh *mesh)
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
Definition: field.hh:399
static Input::Type::Record input_type
double *** concentration_matrix
AbstractRecord & declare_key(const string &key, const KeyType &type, const Default &default_value, const string &description)
Definition: type_record.cc:426
static Input::Type::AbstractRecord input_type
void * xmalloc(size_t size)
Memory allocation with checking.
Definition: system.cc:218
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:34
double m
Definition: che_semchem.h:661
arma::vec3 centre() const
Definition: elements.cc:138
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:167
void set_concentration_matrix(double ***ConcentrationsMatrix, Distribution *conc_distr, int *el_4_loc)
void ctiich(void)
Definition: che_read.cc:561
Record type proxy class.
Definition: type_record.hh:161
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:198
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:390