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