solver.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  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. file.close();
  8. //Init Piccard object
  9. piccard.init(&input_data.geometry);
  10. //Create pool of solutions
  11. for(size_t i=0;i<Time::nT;++i){
  12. Solution* s=new Solution(input_data.geometry);
  13. solutions_stack.push(s);
  14. }
  15. //Init solutions
  16. solutions=new Solution*[Time::nT];
  17. for(size_t i=1;i<Time::nT;++i){
  18. solutions[i]=nullptr;
  19. }
  20. //Init first solution
  21. solutions[0]=new Solution(input_data.geometry);
  22. init_first_solution();
  23. m1=1;
  24. }
  25. void
  26. Solver::init_first_solution(){
  27. Solution& s=*solutions[0];
  28. //Init pressure
  29. for(size_t x=0;x<input_data.geometry.nX;++x){
  30. for(size_t z=0;z<input_data.geometry.nZ[x];++z){
  31. s.P[x][z]=input_data.initial_state->Pinit[x][z];
  32. }
  33. }
  34. //Init hydraulic head
  35. for(size_t x=0;x<input_data.geometry.nX;++x){
  36. s.hydr[x]=input_data.initial_state->hsat[x]+Psat/(Physics::rho*Physics::g);
  37. }
  38. //Init overland level
  39. for(size_t x=0;x<input_data.geometry.nX;++x){
  40. s.hov[x]=Physics::invPsol(input_data.geometry.hsoil[x],s.P[x][input_data.geometry.nZ[x]-1]); //TODO[Chrisophe] à initiliser
  41. }
  42. //Init l
  43. for(size_t x=0;x<input_data.geometry.nX;++x){
  44. double t=input_data.initial_state->hsat[x];
  45. s.l[x]=t;
  46. s.hsat[x]=t;
  47. }
  48. //Init Pl
  49. for(size_t x=0;x<input_data.geometry.nX;++x){
  50. s.Pl[x]=Psat;
  51. }
  52. //Initial state of input_data will be no longer used.
  53. input_data.remove_initial_state();
  54. number_computed_solutions=1;
  55. }
  56. bool
  57. Solver::compute_next_solution(){
  58. //cout<<"[solver::next]"<<endl;
  59. if(m1>1) m1=m1/2;
  60. Solution* s=space_solution();
  61. if(s==nullptr) return false;
  62. solutions[number_computed_solutions++]=s;
  63. //cout<<"[next] done"<<endl;
  64. return true;
  65. }
  66. Solution*
  67. Solver::space_solution(){
  68. #ifdef MYDEBUG
  69. cout<<" [Solver::spaceSolution] start"<<endl;
  70. #endif
  71. size_t n1=0; //we work on time interval [n-1+n1/m1,n-1+(n1+1)/m1]
  72. piccard.previous_solution=solutions[number_computed_solutions-1];
  73. piccard.new_solution=get_new_solution();
  74. piccard.dt=Time::dT/m1*3600;
  75. while(m1<=max_time_subdivisions){
  76. #ifdef MYDEBUG
  77. if(Debug::level>1) cout<<" [Solver::spaceSolution] n1 = "<<n1<<" and m1 = "<<m1<<endl;
  78. #endif
  79. piccard.run();
  80. if(!piccard.has_converged){
  81. m1*=2;
  82. n1=0;
  83. piccard.dt/=2;
  84. piccard.previous_solution=solutions[number_computed_solutions-1];
  85. }
  86. else{
  87. if(n1!=0){//S_in is different form solution[n-1]
  88. release_solution(piccard.previous_solution);
  89. }
  90. ++n1;
  91. if(n1==m1) break;
  92. piccard.previous_solution=piccard.new_solution;
  93. piccard.new_solution=get_new_solution();
  94. }
  95. }
  96. if(m1>max_time_subdivisions){
  97. #ifdef MYDEBUG
  98. cout<<" [Solver::spaceSolution] not converge"<<endl;
  99. #endif
  100. release_solution(piccard.new_solution);
  101. return nullptr;
  102. }
  103. #ifdef MYDEBUG
  104. cout<<" [Solver::spaceSolution] converge"<<endl;
  105. #endif
  106. return piccard.new_solution;
  107. }
  108. }