physics.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #include "physics.hpp"
  2. //------------------------
  3. // Brooks and Corey model
  4. //------------------------
  5. double Physics::g;
  6. double Physics::rho;
  7. double Physics::phi;
  8. double Physics::k0;
  9. double Physics::nivrivsat;
  10. double Physics::Psec;
  11. Physics::Model Physics::model;
  12. double (*Physics::s)(double);
  13. double (*Physics::ds)(double);
  14. void (*Physics::s_ds)(double,double&,double&);
  15. double (*Physics::s_inv)(double);
  16. double (*Physics::kr)(double);
  17. double (*Physics::dkr)(double);
  18. void (*Physics::kr_dkr)(double,double&,double&);
  19. double Physics::model_data[6];
  20. #define sres Physics::model_data[1]
  21. #define lambda Physics::model_data[2]
  22. #define alpha Physics::model_data[3]
  23. void Physics::setModel(Model m){
  24. model=m;
  25. switch(model){
  26. case BrooksCorey:
  27. s=&s_BC;
  28. ds=&ds_BC;
  29. s_ds=&s_ds_BC;
  30. s_inv=&s_inv_BC;
  31. kr=&kr_BC;
  32. dkr=&dkr_BC;
  33. kr_dkr=&kr_dkr_BC;
  34. break;
  35. default:
  36. assert(false);
  37. };
  38. }
  39. double
  40. Physics::s_BC(double P){
  41. if(P>=Psat) return 1;
  42. return sres+(1-sres)*pow(Psat/P,lambda);
  43. }
  44. double
  45. Physics::ds_BC(double P){
  46. if(P>=Psat) return 0;
  47. return ((sres-1)*lambda*pow(Psat/P,lambda))/P;
  48. }
  49. void
  50. Physics::s_ds_BC(double P,double& v,double& dv){
  51. if(P>=Psat){
  52. v=1;
  53. dv=0;
  54. }
  55. else{
  56. double t=(1-sres)*pow(Psat/P,lambda);
  57. v=sres+t;
  58. dv=-(lambda*t)/P;
  59. }
  60. }
  61. double
  62. Physics::s_inv_BC(double S){
  63. return pow((S-sres)/(1-sres),-1/lambda)*Psat;
  64. }
  65. double
  66. Physics::kr_BC(double P){
  67. if(P>=Psat) return 1;
  68. return pow(Psat/P,alpha);
  69. }
  70. double
  71. Physics::dkr_BC(double P){
  72. if(P>=Psat) return 0;
  73. return -alpha*pow(Psat/P,alpha)/P;
  74. }
  75. void
  76. Physics::kr_dkr_BC(double P,double& v,double& dv){
  77. if(P>=Psat){
  78. v=1;
  79. dv=0;
  80. }
  81. else{
  82. double t=pow(Psat/P,alpha);
  83. v=t;
  84. dv=-(alpha*t)/P;
  85. }
  86. }
  87. double
  88. Physics::tilde_a(double l,double hbot){
  89. double t=(l-hbot);
  90. return t*t/(3*k0);
  91. }
  92. double
  93. Physics::tilde_c(double l,double hbot){
  94. return (l-hbot)/(2*k0);
  95. }
  96. void
  97. Physics::save(fstream& file){
  98. file.write((char*)&g,sizeof(double));
  99. file.write((char*)&rho,sizeof(double));
  100. file.write((char*)&phi,sizeof(double));
  101. file.write((char*)&k0,sizeof(double));
  102. file.write((char*)&Psec,sizeof(double));
  103. file.write((char*)&nivrivsat,sizeof(double));
  104. file.write((char*)&model,sizeof(Model));
  105. for(size_t i=0;i<max_model_parameters;++i){
  106. file.write((char*)&model_data[i],sizeof(double));
  107. }
  108. }
  109. void
  110. Physics::load(fstream& file){
  111. file.read((char*)&g,sizeof(double));
  112. file.read((char*)&rho,sizeof(double));
  113. file.read((char*)&phi,sizeof(double));
  114. file.read((char*)&k0,sizeof(double));
  115. file.read((char*)&Psec,sizeof(double));
  116. file.read((char*)&nivrivsat,sizeof(double));
  117. Model m;
  118. file.read((char*)&m,sizeof(Model));
  119. setModel(m);
  120. for(size_t i=0;i<max_model_parameters;++i){
  121. file.read((char*)&model_data[i],sizeof(double));
  122. }
  123. }
  124. double
  125. Physics::Psol(double hsoil,double hov){
  126. double a=Psat-rho*g*nivrivsat;
  127. return rho*g*(hov-hsoil)+a*nivrivsat/(hov-hsoil);
  128. }
  129. double
  130. Physics::dPsol(double hsoil,double hov){
  131. double a=Psat-rho*g*nivrivsat;
  132. double b=hov-hsoil;
  133. return rho*g-a*nivrivsat/(b*b);
  134. }
  135. double
  136. Physics::invPsol(double hsoil,double Psol){
  137. double a=Psat-rho*g*nivrivsat;
  138. double b=a*nivrivsat;
  139. return hsoil+(Psol+sqrt(Psol*Psol-4*rho*g*b))/(2*rho*g);
  140. }