Flow123d  release_3.0.0-1094-g626f1a1
soil_models.hh
Go to the documentation of this file.
1 /*
2  * File: hydro_functions.hh
3  * Author: jb
4  *
5  * Created on May 17, 2010, 1:52 PM
6  */
7 
8 #ifndef _HYDRO_FUNCTIONS_HH
9 #define _HYDRO_FUNCTIONS_HH
10 
11 
12 #include "badiff.h" // for B::d, B::deriv, B::diff, B::getBTypeNameHV, B::o...
13 #include "fadbad.h" // for B
14 namespace internal { class Irmay; }
15 namespace internal { class VanGenuchten; }
16 
17 
18 // todo:
19 // objekt por SoilModel - jedna sada primarnich i pomocnych parametru
20 // konzistentni hydrologicke funkce
21 //
22 // potreboval bych mit vice modelu, z orezavanim i bez nej,
23 // orezavani zpusobuje velke residuum v miste nespojitosti derivace saturace
24 
25 // problem - jak pouzit funktory, FADBAD, aproximace a
26 // inverzi (inverze tlak v zav. na vlhkosti)
27 //
28 // podrobnejsi vyzkum ohledne hydrologickych funkci
29 // vodivost vyplyva s kapilarnich modelu (jak presne?)
30 // co vlhkost?
31 
32 /**
33  * One of possibly more classes specifying dependence of the relative conductivity and the relative water content on the
34  * pressure head. These functions (@p conductivity and @p water_content, respectively) are templates to allow evaluation of
35  * the derivatives through fadbad lib.
36  */
37 
38 struct SoilData {
39  double n; // power parameter
40  double alpha; // pressure head scaling
41  double Qr; // residual water content
42  double Qs; // saturated water content
43  double cut_fraction; // in (0,1), fraction of relative Q where to cut and rescale the retention curve
44  double Ks; // saturated conductivity
45 // double Kk; // conductivity at the cut point
46 };
47 
48 
49 /**
50  * Pure virtual interface, of all models.
51  */
53 public:
55  van_genuchten=0,
56  irmay=1
57  };
58 
59  typedef fadbad::B<double> DiffDouble;
60 
61  virtual void reset(SoilData soil)=0;
62 
63  virtual double conductivity( const double &phead) const =0;
64  virtual auto conductivity_diff(const DiffDouble &p_head)->DiffDouble const =0;
65 
66  virtual double water_content( const double &phead) const =0;
67  virtual auto water_content_diff(const DiffDouble &p_head)->DiffDouble const =0;
68 
69  virtual ~SoilModelBase() {};
70 };
71 
72 
73 template <class Model>
75 public:
76  // We assume that Model have method templates:
77  // template <class T> T conductivity_(const T &h) const;
78  // template <class T> T water_content_(const T &h) const;
79 
80 
81 
83 
84  SoilModelImplBase(double cut_fraction = 0.999);
85 
86  void reset(SoilData data) override;
87 
88  double conductivity( const double &p_head) const override;
89  auto conductivity_diff(const DiffDouble &p_head)->DiffDouble const override;
90 
91  double water_content( const double &p_head) const override;
92  auto water_content_diff(const DiffDouble &p_head)->DiffDouble const override;
93 
95 
96 private:
97  Model model_;
98  double cut_fraction_;
99 };
100 
101 
102 
103 // ************************************** Internal model definitions
104 namespace internal {
105 
107 public:
108  VanGenuchten();
109 
110  void reset_(SoilData soil);
111 
112  template <class T>
113  T conductivity_(const T &h) const;
114 
115  template <class T>
116  T water_content_(const T &h) const;
117 
118 protected:
119 
120  template <class T> T Q_rel(const T &h) const;
121  template <class T> T Q_rel_inv(const T &q) const;
122 
123  // input parameters
125 
126  // constant conductivity parameters
127  double Bpar;
128  double Ppar;
130 
131  // aux values
132  double m;
133  double Qs_nc; // saturated value of continuation of cut water content function
134 
135 
136  double FFQr, FFQs;
137  double Hs;
138 
139 };
140 
141 
142 
143 class Irmay : public VanGenuchten {
144 public:
145  Irmay();
146 
147  template <class T>
148  T conductivity_(const T &h) const;
149 };
150 
151 } // close namespace internal
152 
153 
156 
157 
158 
159 
160 
161 
162 
163 
164 
165 
166 /*
167 
168 //FK-------------------------------------------------------------
169 template <class T>
170 class FK //FK - hydraulic conductivity function
171 {
172 private:
173 // function parameters
174 static const double Bpar; // = 0.5;
175 static const double PPar; // = 2;
176 
177 HydrologyParams par;
178 
179 // auxiliary parameters
180 double Qa,Qm,Qk,m,Hr,Hk,Hs,C1Qee,C2Qee,Qeer,Qees,Qeek;
181 public:
182  FK(const HydrologyParams &par);
183  T operator()(const T& h);
184 };
185 
186 template <class T> const double FK<T>::Bpar =0.5;
187 template <class T> const double FK<T>::PPar =2;
188 
189 template <class T>
190 FK<T> :: FK(const HydrologyParams &par)
191 : par(par)
192 {
193 
194  m = 1-1/par.n;
195 
196  Qa=par.Qr;
197  Qm=par.Qs / par.cut_fraction;
198  //Qk=0.99 * par.Qs;
199  Qk=par.Qs;
200  C1Qee = 1/(Qm - Qa);
201  C2Qee = -Qa/(Qm - Qa);
202 // if (par.cut_fraction >0.9999) {
203 // Hr=-1000;
204 // Hk=Hs=0;
205 // return;
206 // }
207  // fraction =1
208  Qees = C1Qee * par.Qs + C2Qee; // 1
209  Qeek = min(C1Qee * Qk + C2Qee, Qees); // 1
210  Qeer = min(C1Qee * par.Qr + C2Qee, Qeek); // 0
211 
212  Hr = -1/par.alfa*pow(pow(Qeer,-1/m)-1,1/par.n); //
213  Hs = -1/par.alfa*pow(pow(Qees,-1/m)-1,1/par.n);
214  Hk = -1/par.alfa*pow(pow(Qeek,-1/m)-1,1/par.n);
215 
216  cout << "K: Hr, Hs, Hk:" << Hr << " " << Hs << " " << Hk << endl;
217 }
218 
219 template <class T>
220 T FK<T> :: operator()(const T& h)
221 {
222  T Kr,FFQr,FFQ,FFQk,Qee,Qe,Qek,C1Qe,C2Qe,Q;
223 
224  if (h < Hr) return par.Ks*(1E-200); // numericaly zero Kr
225  else
226  if (h < Hk) {
227  Q = Qa + (Qm - Qa)*pow((1 + pow(-par.alfa*h,par.n)),-m);
228  Qee = C1Qee*Q + C2Qee;
229  FFQr = pow(1 - pow(Qeer,1/m),m);
230  FFQ = pow(1 - pow(Qee,1/m),m);
231  FFQk = pow(1 - pow(Qeek,1/m),m);
232  C1Qe = 1/(par.Qs - par.Qr);
233  C2Qe = -par.Qr/(par.Qs - par.Qr);
234  Qe = C1Qe*Q + C2Qe;
235  Qek = C1Qe*Qk + C2Qe;
236  Kr = pow(Qe/Qek,Bpar)*pow((FFQr - FFQ)/(FFQr - FFQk),PPar) * par.Kk/par.Ks;
237  return ( max<T>(par.Ks*Kr,par.Ks*(1E-10)) );
238  }
239  else if(h <= Hs)
240  {
241  Kr = (1-par.Kk/par.Ks)/(Hs-Hk)*(h-Hs) + 1;
242  return ( par.Ks*Kr );
243  }
244  else return par.Ks;
245 }
246 
247 
248 //FQ--------------------------------------------------------------
249 template <class T>
250 class FQ //FQ - water saturation function
251 {
252 HydrologyParams par;
253 // auxiliary parameters
254 double m, Qeer,Qees,Hr,Hs, Qa, Qm;
255 public:
256  FQ(const HydrologyParams &par);
257  T operator()(const T& h);
258 };
259 
260 template <class T>
261 FQ<T>::FQ(const HydrologyParams &par)
262 : par(par)
263 {
264  m = 1 - 1 / par.n;
265 
266 // if (par.cut_fraction >0.9999) {
267 // Hr=-1000;
268 // Hs=0;
269 // return;
270 // }
271  Qm=par.Qs / par.cut_fraction;
272  Qa=par.Qr;
273 
274  Qeer = (par.Qr - Qa)/ (Qm - Qa);
275  Qees = (par.Qs - Qa)/ (Qm - Qa);
276  Hr = -1 / par.alfa * pow( pow(Qeer,-1/m)-1, 1/par.n);
277  Hs = -1 / par.alfa * pow( pow(Qees,-1/m)-1, 1/par.n);
278 
279  cout << "Q: Hr, Hs:" << Hr << " " << Hs << " " << endl;
280 }
281 
282 
283 template <class T>
284 T FQ<T>::operator()(const T& h)
285 {
286  T Qee;
287 
288  if (h < Hr) return par.Qr;
289  else if (h < Hs) {
290  Qee = pow( 1 + pow(-par.alfa * h, par.n), -m);
291  return Qa + (Qm - Qa) * Qee;
292  }
293  else return par.Qs;
294 
295 }
296 
297 //FC--------------------------------------------------------------
298 template <class T>
299 class FC //FC - water capacity function FQ derivative
300 {
301 HydrologyParams par;
302 // auxiliary parameters
303 double m, C1Qee,C2Qee,Qeer,Qees,Hr,Hs, Qa, Qm;
304 public:
305  FC(const HydrologyParams &par);
306  T operator()(const T& h);
307 };
308 
309 template <class T>
310 FC<T>::FC(const HydrologyParams &par)
311 : par(par)
312 {
313  m = 1 - 1 / par.n;
314  Qm=par.Qs / par.cut_fraction;
315  Qa=par.Qr;
316 
317  C1Qee = 1/(Qm - Qa);
318  C2Qee = -Qa/(Qm - Qa);
319  Qeer = C1Qee * par.Qr + C2Qee;
320  Qees = C1Qee * par.Qs + C2Qee;
321  Hr = -1 / par.alfa * pow( pow(Qeer,-1/m)-1, 1/par.n);
322  Hs = -1 / par.alfa * pow( pow(Qees,-1/m)-1, 1/par.n);
323 }
324 
325 
326 template <class T>
327 T FC<T>::operator()(const T& h)
328 {
329  T C1;
330 
331  if (h <= Hr)
332  return 0.0;
333  else if ( h < Hs ) {
334  C1=pow( 1 + pow( -par.alfa * h, par.n), -m-1);
335  return (Qm - Qa) * m * par.n * pow(par.alfa, par.n)*pow(-h, par.n-1)*C1;
336  }
337  else
338  return 0.0;
339 }
340 
341 
342 ! ************************************************************************
343 ! FH - inverse water saturation function
344 ! **************************************
345 real pure function FH_4(h,Matr)
346 implicit none
347 integer,INTENT(IN) :: Matr
348 real, INTENT(IN) :: h
349  FH_4=FH_8(DBLE(h),Matr)
350 end function FH_4
351 
352 double precision pure function FH_8(Qe,Matr)
353 implicit none
354 integer, INTENT(IN) :: Matr
355 double precision,INTENT(IN) :: Qe
356 double precision :: n,m,Qr,Qs,Qa,Qm,Alfa,Q,Qee
357 
358  Qr=par(1,Matr)
359  Qs=par(2,Matr)
360  Qa=par(3,Matr)
361  Qm=par(4,Matr)
362  Alfa=par(5,Matr)
363  n=par(6,Matr)
364  m=1-1/n
365  Q=Qr+(Qs-Qr)*Qe
366  Qee=dmax1((Q-Qa)/(Qm-Qa),1d-3)
367  Qee=dmin1(Qee,1-1d-15)
368  FH_8=-1/Alfa*(Qee**(-1/m)-1)**(1/n)
369 end function FH_8
370 */
371 
372 // Conductivity for analytical solution
373 /*
374 class HydroModel_analytical
375 {
376 public:
377  HydroModel_analytical(ParameterHandler &prm) {};
378 
379  /// Maximum point of capacity. (computed numericaly from eq. atan(x)*2x=1 )
380  inline double cap_arg_max() const { return -0.765378926665788882857; }
381 
382  template <class T>
383  T FK(const T &h) const
384  {
385  if (h>=0.0) return ( 2.0 );
386  return ( 2.0 / (1+h*h) );
387  }
388 
389  template <class T>
390  T FQ(const T &h) const
391  {
392  static T pi_half =std::atan(1.0)*2;
393  if (h>=0.0) return ( 2.0*pi_half*pi_half );
394  T a_tan = atan(h);
395  return ( 2*pi_half*pi_half - a_tan*a_tan );
396  }
397 private:
398  double arg_cap_max;
399 };
400 
401 
402 class HydroModel_linear
403 {
404  HydroModel_linear(ParameterHandler &prm) {};
405 
406 public:
407  template <class T>
408  T FK(const T &h) const {
409  return 1.0;
410  }
411 
412  template <class T>
413  T FQ(const T &h) const {
414  return h;
415  }
416 };
417 
418 */
419 #endif /* _HYDRO_FUNCTIONS_HH */
420 
virtual ~SoilModelBase()
Definition: soil_models.hh:69
double cut_fraction
Definition: soil_models.hh:43
double alpha
Definition: soil_models.hh:40
fadbad::B< double > DiffDouble
Definition: soil_models.hh:59
double Qr
Definition: soil_models.hh:41
double Qs
Definition: soil_models.hh:42
double Ks
Definition: soil_models.hh:44
SoilModelImplBase< internal::Irmay > SoilModel_Irmay
Definition: soil_models.hh:155
SoilModelBase::DiffDouble DiffDouble
Definition: soil_models.hh:82
SoilModelImplBase< internal::VanGenuchten > SoilModel_VanGenuchten
Definition: soil_models.hh:154
double n
Definition: soil_models.hh:39