piccard.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include "piccard.hpp"
  2. namespace Kernel{
  3. Piccard::Piccard(){
  4. previous_solution=nullptr;
  5. new_solution=nullptr;
  6. l=nullptr;
  7. Pl=nullptr;
  8. }
  9. void Piccard::init(const Geometry* geometry_,double** pumps_){
  10. geometry=geometry_;
  11. pumps=pumps_;
  12. horizontal_problem.init(geometry);
  13. overland.init(geometry);
  14. all_vertical_richards.init(geometry,pumps);
  15. if(l!=nullptr) delete[] l;
  16. if(Pl!=nullptr) delete[] Pl;
  17. l=new double[geometry->nX];
  18. Pl=new double[geometry->nX];
  19. error_x=new double[geometry->nX];
  20. }
  21. void
  22. Piccard::run(){
  23. #ifdef MYDEBUG
  24. cout<<" [Piccard::run] start"<<endl;
  25. #endif
  26. double error=0;
  27. //Copy s_in.hsat in l
  28. memcpy(l,previous_solution->hsat,sizeof(double)*geometry->nX);
  29. //Compute Pl from s_in.hsat and s_in.P
  30. compute_Pl(previous_solution->P);
  31. double n1_init_hydr=norm1(previous_solution->hydr,geometry->nX);
  32. double n1_init_hov=norm1(previous_solution->hov,geometry->nX);
  33. //Compute hydr from s_in.hydr, s_in.hsat and Pl
  34. horizontal_problem.previous_hydr=previous_solution->hydr;
  35. horizontal_problem.l=previous_solution->hsat;
  36. horizontal_problem.Pl=Pl;
  37. horizontal_problem.n1_init_hydr=n1_init_hydr;
  38. horizontal_problem.error_x=error_x;
  39. horizontal_problem.run();
  40. swap(new_solution->hydr,horizontal_problem.hydr);
  41. error+=horizontal_problem.total_error;
  42. //Compute Overland
  43. overland.dt=dt;
  44. overland.init_hov=previous_solution->hov;
  45. overland.previous_hov=previous_solution->hov;
  46. overland.P=previous_solution->P;
  47. overland.l=previous_solution->hsat;
  48. overland.Pl=Pl;
  49. overland.hydr=new_solution->hydr;
  50. overland.n1_init_hov=n1_init_hov;
  51. overland.error_x=error_x;
  52. overland.run();
  53. swap(new_solution->hov,overland.hov);
  54. error+=overland.total_error;
  55. //----------------------------------------------
  56. // Apply AllVerticalRichads algorithm to obtain
  57. // - P
  58. // - hsat
  59. //---------------------------------------------
  60. all_vertical_richards.dt=dt;
  61. all_vertical_richards.init_P=previous_solution->P;
  62. all_vertical_richards.previous_P=previous_solution->P;
  63. all_vertical_richards.hydr=new_solution->hydr;
  64. all_vertical_richards.l=previous_solution->hsat;
  65. all_vertical_richards.Pl=Pl;
  66. all_vertical_richards.Psoil=overland.Psoil;
  67. //Specify output (may can change during the run of all_vertical_richards)
  68. all_vertical_richards.hsat=new_solution->hsat;
  69. all_vertical_richards.P=new_solution->P;
  70. all_vertical_richards.error_x=error_x;
  71. all_vertical_richards.init_indice_x_Richards();
  72. all_vertical_richards.run();
  73. new_solution->hsat=all_vertical_richards.hsat;
  74. new_solution->P=all_vertical_richards.P;
  75. size_t k=0;
  76. double previous_error=numeric_limits<double>::infinity();
  77. // Debug::pause();
  78. while(error>=tolerence_Piccard and k<max_iterations_Piccard and (abs(previous_error-error)>tolerence_Piccard/100 or error<oscilation_Piccard)){
  79. previous_error=error;
  80. error=0;
  81. ++k;
  82. #ifdef MYDEBUG
  83. if(Debug::level>1) cout<<" [Piccard::run] k = "<<k<<endl;
  84. #endif
  85. compute_l(l,all_vertical_richards.hsat,error);
  86. #ifdef MYDEBUG
  87. if(Debug::level>1) cout<<" [Piccard::run] error (l) = \033[31m"<<error<<"\033[0m"<<endl;
  88. #endif
  89. compute_Pl(all_vertical_richards.P);
  90. horizontal_problem.previous_hydr=new_solution->hydr;
  91. horizontal_problem.l=l;
  92. horizontal_problem.Pl=Pl;
  93. horizontal_problem.run();
  94. swap(new_solution->hydr,horizontal_problem.hydr);
  95. //new_solution->hydr=horizontal_problem.hydr;
  96. error+=horizontal_problem.total_error;
  97. #ifdef MYDEBUG
  98. if(Debug::level>1) cout<<" [Piccard::run] error (l+hori) = \033[31m"<<error<<"\033[0m"<<endl;
  99. #endif
  100. //Compute Overland
  101. overland.previous_hov=new_solution->hov;
  102. overland.P=new_solution->P;
  103. overland.l=l;
  104. overland.Pl=Pl;
  105. overland.hydr=new_solution->hydr;
  106. overland.run();
  107. swap(new_solution->hov,overland.hov);
  108. error+=overland.total_error;
  109. #ifdef MYDEBUG
  110. if(Debug::level>1) cout<<" [Piccard::run] error (l+hori+overland) = \033[31m"<<error<<"\033[0m"<<endl;
  111. #endif
  112. //Voir calcul indice_x_Richards
  113. all_vertical_richards.init_P=previous_solution->P; //P_0
  114. all_vertical_richards.previous_P=all_vertical_richards.P; //P_{k-1}
  115. all_vertical_richards.hydr=new_solution->hydr;
  116. all_vertical_richards.l=l;
  117. all_vertical_richards.Pl=Pl;
  118. all_vertical_richards.Psoil=overland.Psoil;
  119. //Specify output (may can change during the run of all_vertical_richards)
  120. all_vertical_richards.hsat=new_solution->hsat;
  121. all_vertical_richards.P=new_solution->P;
  122. all_vertical_richards.update_indice_x_Richards();
  123. all_vertical_richards.run();
  124. new_solution->hsat=all_vertical_richards.hsat;
  125. new_solution->P=all_vertical_richards.P;
  126. //we get P_k : all_vertical_richards.P
  127. if(!all_vertical_richards.has_converged){
  128. has_converged=false;
  129. return;
  130. }
  131. }
  132. if(error>=tolerence_Piccard){
  133. #ifdef MYDEBUG
  134. if(Debug::level>1) cout<<" [Piccard]::run not converge"<<endl;
  135. exit(0);
  136. #endif
  137. has_converged=false;
  138. //Voir nettoyage memoire
  139. return;
  140. }
  141. #ifdef MYDEBUG
  142. if(Debug::level>1) cout<<" [Piccard]::run converge"<<endl;
  143. #endif
  144. swap(l,new_solution->l);
  145. swap(Pl,new_solution->Pl);
  146. has_converged=true;
  147. //Voir nettoyage memoire
  148. return;
  149. }
  150. void
  151. Piccard::compute_l(double* h,double* hsat,double& error) {
  152. double e=0;
  153. for(size_t ix=0;ix<geometry->nX;++ix){
  154. double a=h[ix];
  155. double b=max(hsat[ix],a);
  156. l[ix]=b;
  157. double t=b-a;
  158. e+=t*t;
  159. }
  160. error+=sqrt(e);
  161. }
  162. void
  163. Piccard::compute_Pl(double** P){
  164. for(size_t ix=0;ix<geometry->nX;++ix){
  165. double* Px=P[ix];
  166. if(l[ix]==geometry->hsoil[ix]){
  167. Pl[ix]=Px[geometry->nZ[ix]-1];
  168. }
  169. else{
  170. size_t a=(l[ix]-geometry->hbot[ix])/geometry->dZ[ix];
  171. double p1=Px[a];
  172. double p2=Px[a+1];
  173. Pl[ix]=p1+(p2-p1)/geometry->dZ[ix]*(l[ix]-geometry->Z[ix][a]);
  174. }
  175. }
  176. }
  177. }