solver.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. #include "solver.hpp"
  2. namespace Kernel{
  3. Solver::Solver(string filename){
  4. fstream file;
  5. file.open(filename.c_str(),fstream::in|fstream::binary);
  6. input_data.load(file,true);
  7. input_data.geometry.compute_basins();
  8. file.close();
  9. //HACK for pump
  10. for(auto it=input_data.source.pumps.begin();it!=input_data.source.pumps.end();++it){
  11. Pump& P=*(*it);
  12. double lX=input_data.geometry.lX;
  13. P.left_init*=lX;
  14. P.right_init*=lX;
  15. P.delta_left_init*=lX;
  16. P.delta_right_init*=lX;
  17. P.left_final*=lX;
  18. P.right_final*=lX;
  19. P.delta_left_final*=lX;
  20. P.delta_right_final*=lX;
  21. }
  22. pumps=new double*[input_data.geometry.nX];
  23. for(size_t ix=0;ix<input_data.geometry.nX;++ix){
  24. pumps[ix]=new double[input_data.geometry.nZ[ix]];
  25. }
  26. //Init Piccard object
  27. piccard.init(&input_data.geometry,pumps);
  28. //Create pool of solutions
  29. for(size_t i=0;i<Time::nT;++i){
  30. Solution* s=new Solution(input_data.geometry);
  31. solutions_stack.push(s);
  32. }
  33. //Init solutions
  34. solutions=new Solution*[Time::nT];
  35. for(size_t i=1;i<Time::nT;++i){
  36. solutions[i]=nullptr;
  37. }
  38. //Init first solution
  39. solutions[0]=new Solution(input_data.geometry);
  40. init_first_solution();
  41. m1=1;
  42. }
  43. void
  44. Solver::init_first_solution(){
  45. Solution& s=*solutions[0];
  46. //Init pressure
  47. for(size_t x=0;x<input_data.geometry.nX;++x){
  48. for(size_t z=0;z<input_data.geometry.nZ[x];++z){
  49. s.P[x][z]=input_data.initial_state->Pinit[x][z];
  50. }
  51. }
  52. //Init hydraulic head
  53. for(size_t x=0;x<input_data.geometry.nX;++x){
  54. s.hydr[x]=input_data.initial_state->hsat[x]+Psat/(Physics::rho*Physics::g);
  55. }
  56. //[Obsolete]
  57. ////Init overland level
  58. //for(size_t x=0;x<input_data.geometry.nX;++x){
  59. // s.hov[x]=Physics::invPsol(input_data.geometry.hsoil[x],s.P[x][input_data.geometry.nZ[x]-1]); //TODO[Chrisophe] à initiliser
  60. //}
  61. for(size_t x=0;x<input_data.geometry.nX;++x){
  62. s.hov[x]=input_data.initial_state->hov[x];
  63. }
  64. //Init l
  65. for(size_t x=0;x<input_data.geometry.nX;++x){
  66. double t=input_data.initial_state->hsat[x];
  67. s.l[x]=t;
  68. s.hsat[x]=t;
  69. }
  70. //Init Pl
  71. for(size_t x=0;x<input_data.geometry.nX;++x){
  72. s.Pl[x]=Psat;
  73. }
  74. //Initial state of input_data will be no longer used.
  75. input_data.remove_initial_state();
  76. number_computed_solutions=1;
  77. }
  78. bool
  79. Solver::compute_next_solution(){
  80. //cout<<"[solver::next]"<<endl;
  81. compute_sources(number_computed_solutions*Time::dT);
  82. if(m1>1) m1=m1/2;
  83. Solution* s=space_solution();
  84. if(s==nullptr) return false;
  85. solutions[number_computed_solutions++]=s;
  86. //cout<<"[next] done"<<endl;
  87. return true;
  88. }
  89. Solution*
  90. Solver::space_solution(){
  91. #ifdef MYDEBUG
  92. cout<<" [Solver::spaceSolution] start"<<endl;
  93. #endif
  94. size_t n1=0; //we work on time interval [n-1+n1/m1,n-1+(n1+1)/m1]
  95. piccard.previous_solution=solutions[number_computed_solutions-1];
  96. piccard.new_solution=get_new_solution();
  97. piccard.dt=Time::dT/m1*3600;
  98. while(m1<=max_time_subdivisions){
  99. #ifdef MYDEBUG
  100. if(Debug::level>1) cout<<" [Solver::spaceSolution] n1 = "<<n1<<" and m1 = "<<m1<<endl;
  101. #endif
  102. piccard.run();
  103. if(!piccard.has_converged){
  104. if(n1!=0){//S_in is different form solution[n-1]
  105. release_solution(piccard.previous_solution);
  106. }
  107. m1*=2;
  108. n1=0;
  109. piccard.dt/=2;
  110. piccard.previous_solution=solutions[number_computed_solutions-1];
  111. }
  112. else{
  113. if(n1!=0){//S_in is different form solution[n-1]
  114. release_solution(piccard.previous_solution);
  115. }
  116. ++n1;
  117. if(n1==m1) break;
  118. piccard.previous_solution=piccard.new_solution;
  119. piccard.new_solution=get_new_solution();
  120. }
  121. }
  122. if(m1>max_time_subdivisions){
  123. #ifdef MYDEBUG
  124. cout<<" [Solver::spaceSolution] not converge"<<endl;
  125. #endif
  126. release_solution(piccard.new_solution);
  127. return nullptr;
  128. }
  129. #ifdef MYDEBUG
  130. cout<<" [Solver::spaceSolution] converge"<<endl;
  131. #endif
  132. return piccard.new_solution;
  133. }
  134. void Solver::compute_sources(double t){
  135. for(size_t ix=0;ix<input_data.geometry.nX;++ix){
  136. double x=ix*input_data.geometry.dX;
  137. for(size_t iz=0;iz<input_data.geometry.nZ[ix];++iz){
  138. double z=input_data.geometry.hbot[ix]+iz*input_data.geometry.dZ[ix];
  139. pumps[ix][iz]=0;
  140. for(auto it=input_data.source.pumps.begin();it!=input_data.source.pumps.end();++it){
  141. double p=(*it)->value(x,z,t/Time::T);
  142. pumps[ix][iz]+=p;
  143. }
  144. }
  145. }
  146. }
  147. }