overland.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include "overland.hpp"
  2. #include "debug.hpp"
  3. namespace Kernel{
  4. void Overland::run(){
  5. #ifdef MYDEBUG
  6. cout<<" [Overland::run] start"<<endl;
  7. #endif
  8. compute_flux_soil();
  9. total_error=0;
  10. for(size_t ix=0;ix<geometry->nX;++ix){
  11. hov[ix]=init_hov[ix]-dt*flux_soil[ix];
  12. //TODO :: add rain
  13. if(ix>89){
  14. hov[ix]+=dt*0.0001;
  15. }
  16. }
  17. apply_flow();
  18. for(size_t ix=0;ix<geometry->nX;++ix){
  19. double e=abs(hov[ix]-previous_hov[ix])/n1_init_hov;
  20. error_x[ix]+=e;
  21. total_error+=e;
  22. Psoil[ix]=Physics::Psoil(geometry->hsoil[ix],hov[ix]);
  23. }
  24. #ifdef MYDEBUG
  25. cout<<" [Overland::run] error : "<<total_error<<endl;
  26. #endif
  27. #ifdef MYDEBUG
  28. cout<<" [Overland::run] end"<<endl;
  29. #endif
  30. }
  31. void Overland::compute_flux_soil(){
  32. for(size_t ix=0;ix<geometry->nX;++ix){
  33. double p1=P[ix][geometry->nZ[ix]-1];
  34. double p2=P[ix][geometry->nZ[ix]-2];
  35. double flux=Physics::k0/2*(Physics::kr(p1)+Physics::kr(p2))*((p1-p2)/(geometry->dZ[ix]*Physics::rho*Physics::g)+1);
  36. if(ix==0) flux-=Physics::k0*Physics::kr(Pl[0]+Physics::rho*Physics::g*(l[0]-geometry->hsoil[0]))*(hydr[1]-hydr[0])*geometry->dhsoil[0]/geometry->dX;
  37. else if(ix==geometry->nX-1) flux-=Physics::k0*Physics::kr(Pl[ix]+Physics::rho*Physics::g*(l[ix]-geometry->hsoil[ix]))*(hydr[ix]-hydr[ix-1])*geometry->dhsoil[ix]/geometry->dX;
  38. else flux-=Physics::k0*Physics::kr(Pl[ix]+Physics::rho*Physics::g*(l[ix]-geometry->hsoil[ix]))*(hydr[ix+1]-hydr[ix-1])/2*geometry->dhsoil[ix]/geometry->dX;
  39. flux_soil[ix]=flux;
  40. }
  41. }
  42. void Overland::apply_flow(){
  43. bool overflow=true;
  44. while(overflow){
  45. overflow=false;
  46. runoff_to_local_min();
  47. basin_transfer();
  48. }
  49. }
  50. void Overland::runoff_to_local_min(){
  51. // cout<<" [Overland::runoff_to_local_min]"<<endl;
  52. for(size_t ix=0;ix<geometry->nX;++ix){
  53. double dh=hov[ix]-geometry->hsoil[ix]-Physics::minimal_height_to_runoff;
  54. if(dh>0){
  55. double dh_left,dh_right;
  56. switch(geometry->runoff_directions[ix]){
  57. case Left:
  58. dh_left=dh;
  59. dh_right=0;
  60. break;
  61. case Right:
  62. dh_right=dh;
  63. dh_left=0;
  64. break;
  65. case Both:
  66. dh_left=dh/2;
  67. dh_right=dh/2;
  68. break;
  69. default:
  70. dh_left=0;
  71. dh_right=0;
  72. break;
  73. }
  74. size_t jx=ix;
  75. while(dh_left>0){
  76. --jx;
  77. if(geometry->runoff_directions[jx]==None or geometry->runoff_directions[jx]==Right){
  78. hov[jx]+=dh_left;
  79. hov[ix]-=dh_left;
  80. break;
  81. }
  82. else{
  83. double temp=min(max(Physics::minimal_height_to_runoff-hov[jx]+geometry->hsoil[jx],0.0),dh_left);
  84. hov[jx]+=temp;
  85. hov[ix]-=temp;
  86. dh_left-=temp;
  87. }
  88. }
  89. jx=ix;
  90. while(dh_right>0){
  91. ++jx;
  92. if(geometry->runoff_directions[jx]==None or geometry->runoff_directions[jx]==Left){
  93. hov[jx]+=dh_right;
  94. hov[ix]-=dh_right;
  95. break;
  96. }
  97. else{
  98. double temp=min(max(Physics::minimal_height_to_runoff-hov[jx]+geometry->hsoil[jx],0.0),dh_right);
  99. hov[jx]+=temp;
  100. hov[ix]-=temp;
  101. dh_right-=temp;
  102. }
  103. }
  104. }
  105. }
  106. /*cout<<"------------------- after runoff ----------------"<<endl;
  107. for(size_t ix=0;ix<100;++ix){
  108. cout<<ix<<" : "<<max(0.0,hov[ix]-geometry->hsoil[ix]-Physics::minimal_height_to_runoff)<<endl;;
  109. }*/
  110. }
  111. void Overland::basin_transfer(){
  112. double vol_tot=0;
  113. for(size_t ix=0;ix<geometry->nX;++ix){
  114. vol_tot+=max(hov[ix]-geometry->hsoil[ix],0.0);
  115. }
  116. //TODO :: Remove guard
  117. int nmax=100;
  118. do{
  119. --nmax;
  120. geometry->root_basin->compute_vflow(geometry->hsoil,hov);
  121. geometry->root_basin->repartition(geometry->hsoil,hov,geometry->runoff_directions);
  122. }while(geometry->root_basin->overflow and nmax>0);
  123. if(nmax==0){
  124. cerr<<"Too many loop"<<endl;
  125. Debug::pause();//exit(-1);
  126. }
  127. geometry->root_basin->compute_vflow(geometry->hsoil,hov);
  128. double vol_tot_mid=0;
  129. for(size_t ix=0;ix<geometry->nX;++ix){
  130. vol_tot_mid+=max(hov[ix]-geometry->hsoil[ix],0.0);
  131. }
  132. geometry->root_basin->flatten(geometry->hsoil,hov);
  133. double vol_tot_new=0;
  134. for(size_t ix=0;ix<geometry->nX;++ix){
  135. vol_tot_new+=max(hov[ix]-geometry->hsoil[ix],0.0);
  136. }
  137. }
  138. }