piccard.cpp 5.4 KB

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