geometry.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. #include "geometry.hpp"
  2. double inf = numeric_limits<double>::infinity();
  3. Geometry::Geometry(){
  4. lX=0;
  5. nX=0;
  6. dX=0;
  7. hsoil=nullptr;
  8. dhsoil=nullptr;
  9. hbot=nullptr;
  10. dhbot=nullptr;
  11. nZ=nullptr;
  12. dZ=nullptr;
  13. Z=nullptr;
  14. }
  15. Geometry::~Geometry(){
  16. if(hsoil!=nullptr){
  17. delete[] hsoil;
  18. delete[] dhsoil;
  19. delete[] hbot;
  20. delete[] dhbot;
  21. delete[] dZ;
  22. delete[] nZ;
  23. for(size_t i=0;i<nX;++i){
  24. delete[] Z[i];
  25. }
  26. delete[] Z;
  27. }
  28. }
  29. void
  30. Geometry::initZ(double dZ_avg,bool init){
  31. if(init){
  32. nZ=new size_t[nX];
  33. dZ=new double[nX];
  34. Z=new double*[nX];
  35. }
  36. for(size_t k=0;k<nX;++k){
  37. double d=hsoil[k]-hbot[k];
  38. size_t n=d/dZ_avg;
  39. double dz=d/n;
  40. dZ[k]=dz;
  41. nZ[k]=n+1;
  42. if(init) Z[k]=new double[n+1];
  43. for(size_t j=0;j<n+1;++j){
  44. Z[k][j]=hbot[k]+j*dz;
  45. }
  46. }
  47. }
  48. void
  49. Geometry::save(fstream& file) {
  50. file.write((char*)&lX,sizeof(double));
  51. file.write((char*)&nX,sizeof(size_t));
  52. file.write((char*)&dX,sizeof(double));
  53. file.write((char*)hsoil,nX*sizeof(double));
  54. file.write((char*)dhsoil,nX*sizeof(double));
  55. file.write((char*)hbot,nX*sizeof(double));
  56. file.write((char*)dhbot,nX*sizeof(double));
  57. file.write((char*)nZ,nX*sizeof(size_t));
  58. file.write((char*)dZ,nX*sizeof(double));
  59. for(size_t i=0;i<nX;++i){
  60. file.write((char*)Z[i],nZ[i]*sizeof(double));
  61. }
  62. }
  63. void
  64. Geometry::load(fstream& file,bool init) {
  65. file.read((char*)&lX,sizeof(double));
  66. file.read((char*)&nX,sizeof(size_t));
  67. file.read((char*)&dX,sizeof(double));
  68. if(init){
  69. hsoil=new double[nX];
  70. dhsoil=new double[nX];
  71. hbot=new double[nX];
  72. dhbot=new double[nX];
  73. nZ=new size_t[nX];
  74. dZ=new double[nX];
  75. Z=new double*[nX];
  76. }
  77. file.read((char*)hsoil,nX*sizeof(double));
  78. file.read((char*)dhsoil,nX*sizeof(double));
  79. file.read((char*)hbot,nX*sizeof(double));
  80. file.read((char*)dhbot,nX*sizeof(double));
  81. file.read((char*)nZ,nX*sizeof(size_t));
  82. file.read((char*)dZ,nX*sizeof(double));
  83. for(size_t i=0;i<nX;++i){
  84. if(init) Z[i]=new double[nZ[i]];
  85. file.read((char*)Z[i],nZ[i]*sizeof(double));
  86. }
  87. //Comoute dhsoil and dhbot
  88. dhsoil[0]=(hsoil[1]-hsoil[0])/dX;
  89. dhbot[0]=(hbot[1]-hbot[0])/dX;
  90. for(size_t i=1;i<nX-1;++i){
  91. dhsoil[i]=(hsoil[i+1]-hsoil[i-1])/(2*dX);
  92. dhbot[i]=(hbot[i+1]-hbot[i-1])/(2*dX);
  93. }
  94. dhsoil[nX-1]=(hsoil[nX-1]-hsoil[nX-2])/dX;
  95. dhbot[nX-1]=(hbot[nX-1]-hbot[nX-2])/dX;
  96. cout<<"Done"<<endl;
  97. }
  98. pair<list<Basin*>::iterator,list<Basin*>::iterator>
  99. Geometry::find_basins(const Summit& s,list<Basin*>& basins){
  100. list<Basin*>::iterator it_left;
  101. list<Basin*>::iterator it_right;
  102. for(list<Basin*>::iterator it=basins.begin();it!=basins.end();++it){
  103. Basin* b=*it;
  104. if(b->xleft==s.ix){
  105. cout<<"Right found"<<endl;
  106. it_right=it;
  107. }
  108. if(b->xright==s.ix){
  109. cout<<"Left found"<<endl;
  110. it_left=it;
  111. }
  112. }
  113. return pair<list<Basin*>::iterator,list<Basin*>::iterator>(it_left,it_right);
  114. }
  115. void Geometry::compute_basins(){
  116. //Find local min point of hsoil
  117. vector<size_t> v_min;
  118. if(hsoil[0]<hsoil[1]) v_min.push_back(0);
  119. for(size_t ix=1;ix<nX-1;++ix){
  120. double h=hsoil[ix];
  121. if(hsoil[ix-1]>h and h<hsoil[ix+1]) v_min.push_back(ix);
  122. }
  123. if(hsoil[nX-2]>hsoil[nX-1]) v_min.push_back(nX-1);
  124. size_t nb=v_min.size();
  125. //Primitive Basins
  126. vector<Summit> summits;
  127. list<Basin*> basins_to_merge;
  128. for(size_t ib=0;ib<nb;++ib){
  129. Basin* b=new Basin;
  130. size_t xb=v_min[ib];
  131. //Find left bound
  132. b->xbottom=xb;
  133. if(xb==0){
  134. b->xleft=xb;
  135. b->position=BorderLeft;
  136. }
  137. else{
  138. size_t ix=xb;
  139. while(ix>0 and hsoil[ix-1]>hsoil[ix]) --ix;
  140. b->xleft=ix;
  141. if(ix==0) b->position=BorderLeft;
  142. if(ix>0) summits.emplace_back(ix,hsoil[ix]);
  143. }
  144. //Find right bound
  145. if(xb==nX-1){
  146. b->xright=xb;
  147. b->position=BorderRight;
  148. }
  149. else{
  150. size_t ix=xb;
  151. while(ix<nX and hsoil[ix+1]>hsoil[ix]) ++ix;
  152. if(ix==nX-1)b->position=BorderRight;
  153. b->xright=ix;
  154. }
  155. b->hleft=hsoil[b->xleft];
  156. b->hright=hsoil[b->xright];
  157. b->compute_leak_direction();
  158. // Set hmin
  159. b->hmin=hsoil[xb];
  160. basins_to_merge.push_back(b);
  161. }
  162. //Determine meta basins`
  163. sort(summits.begin(),summits.end());
  164. for(auto it=summits.begin();it!=summits.end();++it){
  165. Summit& s=*it;
  166. auto res=find_basins(s,basins_to_merge);
  167. list<Basin*>::iterator it_left=res.first;
  168. list<Basin*>::iterator it_right=res.second;
  169. Basin* b_left=*it_left;
  170. Basin* b_right=*it_right;
  171. basins_to_merge.erase(it_left);
  172. basins_to_merge.erase(it_right);
  173. Basin* b=new Basin(b_left,b_right);
  174. basins_to_merge.push_back(b);
  175. }
  176. root_basin=basins_to_merge.front();
  177. root_basin->display();
  178. // Compute Runoff directions
  179. runoff_directions=new Direction[nX];
  180. for(size_t ix=1;ix<nX-1;++ix){
  181. double dh=(hsoil[ix+1]-hsoil[ix-1])/(2*dX);
  182. if(abs(dh)<max_slope_both_side_runoff) runoff_directions[ix]=Both;
  183. else runoff_directions[ix]=(dh>0)?Left:Right;
  184. cout<<ix<<" "<<dh<<" "<<runoff_directions[ix]<<endl;
  185. }
  186. }