XBeach
|
00001 module morphevolution 00002 implicit none 00003 save 00004 00005 #ifdef HAVE_CONFIG_H 00006 #include "config.h" 00007 #endif 00008 contains 00009 subroutine transus(s,par) 00010 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00011 ! Copyright (C) 2007 UNESCO-IHE, WL|Delft Hydraulics and Delft University ! 00012 ! Dano Roelvink, Ap van Dongeren, Ad Reniers, Jamie Lescinski, ! 00013 ! Jaap van Thiel de Vries, Robert McCall ! 00014 ! ! 00015 ! d.roelvink@unesco-ihe.org ! 00016 ! UNESCO-IHE Institute for Water Education ! 00017 ! P.O. Box 3015 ! 00018 ! 2601 DA Delft ! 00019 ! The Netherlands ! 00020 ! ! 00021 ! This library is free software; you can redistribute it and/or ! 00022 ! modify it under the terms of the GNU Lesser General Public ! 00023 ! License as published by the Free Software Foundation; either ! 00024 ! version 2.1 of the License, or (at your option) any later version. ! 00025 ! ! 00026 ! This library is distributed in the hope that it will be useful, ! 00027 ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! 00028 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 00029 ! Lesser General Public License for more details. ! 00030 ! ! 00031 ! You should have received a copy of the GNU Lesser General Public ! 00032 ! License along with this library; if not, write to the Free Software ! 00033 ! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ! 00034 ! USA ! 00035 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00036 use params 00037 use spaceparams 00038 use xmpi_module 00039 use interp 00040 use paramsconst 00041 ! use vsmumod 00042 00043 implicit none 00044 00045 type(spacepars),target :: s 00046 type(parameters) :: par 00047 00048 integer :: i,isig 00049 integer :: j,jg 00050 real*8 :: exp_ero 00051 00052 real*8,dimension(:),allocatable,save :: chain,cumchain 00053 real*8,dimension(:,:),allocatable,save :: vmag2,uau,uav,um,vm,ueu_sed,uev_sed,veu_sed,vev_sed 00054 real*8,dimension(:,:),allocatable,save :: ccvt,dcdz,dsigt,aref 00055 real*8,dimension(:,:),allocatable,save :: cc,ccb,cu,cv,Sus,Svs 00056 real*8,dimension(:,:),allocatable,save :: cub,cvb,Sub,Svb,pbbedu,pbbedv 00057 real*8,dimension(:,:),allocatable,save :: suq3d,svq3d,eswmax,eswbed,sigs,deltas 00058 real*8,dimension(:,:,:),allocatable,save :: dsig,ccv,sdif,cuq3d,cvq3d,fac 00059 logical,dimension(:,:),allocatable,save :: bermslopeindexbed,bermslopeindexsus,bermslopeindex 00060 00061 real*8,dimension(:,:),allocatable,save :: sinthm,costhm 00062 00063 real*8 :: delta,delta_x,shields,ftheta,psi_x,Sbtot ! Lodewijk: for direction of sediment transport (bed slope effect) 00064 real*8 :: Ssmtot, dzbds, Sbmtot ! Lodewijk: for magnitude of sediment transport (bed slope effect) 00065 00066 !include 's.ind' 00067 !include 's.inp' 00068 00069 if (.not. allocated(vmag2)) then 00070 allocate(vmag2 (s%nx+1,s%ny+1)) 00071 allocate(uau (s%nx+1,s%ny+1)) 00072 allocate(uav (s%nx+1,s%ny+1)) 00073 allocate(ueu_sed (s%nx+1,s%ny+1)) 00074 allocate(uev_sed (s%nx+1,s%ny+1)) 00075 allocate(veu_sed (s%nx+1,s%ny+1)) 00076 allocate(vev_sed (s%nx+1,s%ny+1)) 00077 allocate(cu (s%nx+1,s%ny+1)) 00078 allocate(cv (s%nx+1,s%ny+1)) 00079 allocate(cc (s%nx+1,s%ny+1)) 00080 allocate(ccb (s%nx+1,s%ny+1)) 00081 allocate(fac (s%nx+1,s%ny+1,par%ngd)) 00082 allocate(Sus (s%nx+1,s%ny+1)) 00083 allocate(Svs (s%nx+1,s%ny+1)) 00084 allocate(cub (s%nx+1,s%ny+1)) 00085 allocate(cvb (s%nx+1,s%ny+1)) 00086 allocate(Sub (s%nx+1,s%ny+1)) 00087 allocate(Svb (s%nx+1,s%ny+1)) 00088 allocate(pbbedu (s%nx+1,s%ny+1)) 00089 allocate(pbbedv (s%nx+1,s%ny+1)) 00090 allocate(ccvt (s%nx+1,s%ny+1)) 00091 allocate(dcdz (s%nx+1,s%ny+1)) 00092 allocate(dsigt (s%nx+1,s%ny+1)) 00093 allocate(dsig(s%nx+1,s%ny+1,par%kmax)) 00094 allocate(ccv(s%nx+1,s%ny+1,par%kmax)) 00095 allocate(sdif(s%nx+1,s%ny+1,par%kmax)) 00096 allocate(um (s%nx+1,s%ny+1)) 00097 allocate(vm (s%nx+1,s%ny+1)) 00098 allocate(deltas(s%nx+1,s%ny+1)) 00099 allocate(sigs(s%nx+1,s%ny+1)) 00100 allocate(eswmax(s%nx+1,s%ny+1)) 00101 allocate(eswbed(s%nx+1,s%ny+1)) 00102 allocate(suq3d(s%nx+1,s%ny+1)) 00103 allocate(svq3d(s%nx+1,s%ny+1)) 00104 allocate(cuq3d(s%nx+1,s%ny+1,par%kmax)) 00105 allocate(cvq3d(s%nx+1,s%ny+1,par%kmax)) 00106 allocate(aref(s%nx+1,s%ny+1)) 00107 allocate(chain(par%kmax)) 00108 allocate(cumchain(par%kmax)) 00109 allocate (sinthm(s%nx+1,s%ny+1)) 00110 allocate (costhm(s%nx+1,s%ny+1)) 00111 allocate(bermslopeindexbed(s%nx+1,s%ny+1)) 00112 allocate(bermslopeindexsus(s%nx+1,s%ny+1)) 00113 allocate(bermslopeindex(s%nx+1,s%ny+1)) 00114 00115 delta_x = 0.d0 ! Lodewijk 00116 shields = 0.d0 ! Lodewijk 00117 ftheta = 0.d0 ! Lodewijk 00118 psi_x = 0.d0 ! Lodewijk 00119 Sbtot = 0.d0 ! Lodewijk 00120 delta = 0.d0 ! Lodewijk 00121 uau = 0.d0 00122 uav = 0.d0 00123 um = 0.d0 00124 vm = 0.d0 00125 chain = 0.0d0 00126 cumchain = 0.0d0 00127 fac = 1.d0 00128 exp_ero = 0.d0 00129 ! generate sigma grid shape... 00130 do isig=2,par%kmax 00131 chain(isig) = par%sigfac**(isig-1) 00132 cumchain(isig) = cumchain(isig-1)+chain(isig) 00133 enddo 00134 bermslopeindex = .false. ! turned off unless needed 00135 bermslopeindexbed = .false. 00136 bermslopeindexsus = .false. 00137 endif 00138 00139 ! use eulerian velocities 00140 vmag2 = s%ue**2+s%ve**2 00141 cu = 0.0d0 00142 cv = 0.0d0 00143 cub = 0.0d0 00144 cvb = 0.0d0 00145 s%dcsdx = 0.0d0 00146 s%dcsdy = 0.0d0 00147 00148 sinthm = sin(s%thetamean-s%alfaz) 00149 costhm = cos(s%thetamean-s%alfaz) 00150 00151 ! short wave runup 00152 if (par%swrunup==1 .and. par%struct==1) then 00153 call hybrid(s,par) 00154 endif 00155 00156 ! compute turbulence due to wave breaking 00157 if (par%lwt==1 .or. par%turb == TURB_BORE_AVERAGED .or. par%turb == TURB_WAVE_AVERAGED) then 00158 call waveturb(s,par) 00159 endif 00160 00161 if (par%swave==1) then 00162 ! include wave skewness and assymetry in sediment advection velocity 00163 if (par%waveform==WAVEFORM_RUESSINK_VANRIJN)then 00164 call RvR(s,par) 00165 elseif (par%waveform==WAVEFORM_VANTHIEL) then 00166 call vT(s,par) 00167 endif 00168 00169 endif 00170 00171 ! calculate equilibrium concentration/sediment source 00172 select case (par%form) 00173 case (FORM_SOULSBY_VANRIJN,FORM_VANTHIEL_VANRIJN,FORM_VANRIJN1993) 00174 ! Soulsby van Rijn and Van Thiel de Vries & Reniers 2008 formulations 00175 call sedtransform(s,par) 00176 case (FORM_NIELSEN2006) 00177 call Nielsen2006(s,par) 00178 if (par%bulk==0) then 00179 return 00180 endif 00181 case (FORM_MCCALL_VANRIJN) 00182 call mccall_vanrijn(s,par) 00183 if (par%bulk==0) then 00184 return 00185 endif 00186 end select 00187 00188 ! compute reduction factor for sediment sources due to presence of hard layers 00189 do jg = 1,par%ngd 00190 do j=1,s%ny+1 00191 do i=1,s%nx+1 00192 exp_ero = par%morfac*par%dt/(1.d0-par%por)*s%hh(i,j)*(s%ceqsg(i,j,jg)*s%pbbed(i,j,1,jg)/s%Tsg(i,j,jg) & 00193 + s%ceqbg(i,j,jg)*s%pbbed(i,j,1,jg)/par%dt) 00194 ! limit erosion to available sediment on top of hard layer wwvv changed tiny into epsilon 00195 fac(i,j,jg) = min(1.d0,s%structdepth(i,j)*s%pbbed(i,j,1,jg)/max(epsilon(0.d0),exp_ero) ) 00196 !if (fac(i,j,jg)*exp_ero > dzbed(i,j,1)*pbbed(i,j,1,jg)) then 00197 ! limit erosion to available sand in top layer 00198 ! fac(i,j,jg) = min(fac(i,j,jg),dzbed(i,j,1)*pbbed(i,j,1,jg)/max(tiny(0.d0),exp_ero) ) 00199 ! write(*,*)'WARNING: expected erosion from top layer is larger than available sand in top layer' 00200 !endif 00201 enddo 00202 enddo 00203 enddo 00204 00205 ! compute diffusion coefficient 00206 s%Dc = par%facDc*s%nuh 00207 !Robert: removed this which is not grid-independent s%Dc = (par%nuh+par%nuhfac*s%hh*(s%DR/par%rho)**(1.d0/3.d0)) 00208 00209 do jg = 1,par%ngd 00210 cc = s%ccg(:,:,jg) 00211 if (s%D50(jg)>0.002d0) then 00212 ! RJ: set ceqsg to zero for gravel. 00213 ! Dano: try without this fix cc = 0.d0 ! Can be used to test total transport mode 00214 endif 00215 ! 00216 ! X-direction 00217 ! 00218 ! Get ua in u points and split out in u and v direction 00219 uau(1:s%nx,:) = 0.5*(s%ua(1:s%nx,:)*costhm(1:s%nx,:)+s%ua(2:s%nx+1,:)*costhm(1:s%nx,:)) 00220 uav(1:s%nx,:) = 0.5*(s%ua(1:s%nx,:)*sinthm(1:s%nx,:)+s%ua(2:s%nx+1,:)*sinthm(1:s%nx,:)) 00221 if (par%nz>1) then 00222 ueu_sed(1:s%nx,:) = 0.5*(s%ue_sed(1:s%nx,:)+s%ue_sed(2:s%nx+1,:)) 00223 else 00224 ueu_sed=s%ueu 00225 endif 00226 veu_sed(1:s%nx,:) = 0.5*(s%ve_sed(1:s%nx,:)+s%ve_sed(2:s%nx+1,:)) 00227 if (xmpi_isbot) then 00228 veu_sed(s%nx+1,:) = veu_sed(s%nx,:) 00229 endif 00230 00231 ! Compute vmagu including ua 00232 ! s%vmagu = sqrt((s%uu+uau)**2+(s%vu+uav)**2) 00233 s%vmagu = sqrt((ueu_sed+uau)**2+(veu_sed+uav)**2) 00234 ! sediment advection velocity for suspended load and bed load respectively 00235 ! REMARK: when vreps does not equal vv; no mass conservation 00236 ! s%ureps = s%ueu+uau 00237 ! s%urepb = s%ueu+uau ! RJ maybe reduce this velocity? 00238 s%ureps = ueu_sed+uau 00239 s%urepb = ueu_sed+uau 00240 ! 00241 do j=1,s%ny+1 00242 do i=1,s%nx 00243 if(s%ureps(i,j)>0.d0) then 00244 ! test cu(i,j)=cc(i,j) 00245 cu(i,j)=par%thetanum*cc(i,j)+(1.d0-par%thetanum)*cc(min(i+1,s%nx),j) 00246 cub(i,j)=par%thetanum*s%pbbed(i,j,1,jg)*s%ceqbg(i,j,jg)+(1.d0-par%thetanum)& 00247 *s%pbbed(min(i+1,s%nx),j,1,jg)*s%ceqbg(min(i+1,s%nx),j,jg) 00248 !cub(i,j)=par%thetanum*ccb(i,j)+(1.d0-par%thetanum)*ccb(min(i+1,nx),j) 00249 elseif(s%ureps(i,j)<0.d0) then 00250 cu(i,j)=par%thetanum*cc(i+1,j)+(1.d0-par%thetanum)*cc(max(i,2),j) 00251 cub(i,j)=par%thetanum*s%pbbed(i+1,j,1,jg)*s%ceqbg(i+1,j,jg)+(1.d0-par%thetanum)& 00252 *s%pbbed(max(i,2),j,1,jg)*s%ceqbg(max(i,2),j,jg) 00253 !cub(i,j)=par%thetanum*ccb(i+1,j)+(1.d0-par%thetanum)*ccb(max(i,2),j) 00254 else 00255 cu(i,j)=0.5d0*(cc(i,j)+cc(i+1,j)) 00256 cub(i,j)=0.5d0*(s%pbbed(i,j,1,jg)*s%ceqbg(i,j,jg)+s%pbbed(i+1,j,1,jg)*s%ceqbg(i+1,j,jg)) 00257 !cub(i,j)=0.5d0*(ccb(i,j)+ccb(i+1,j)) 00258 endif 00259 s%dcsdx(i,j)=(cc(i+1,j)-cc(i,j))/s%dsu(i,j) 00260 enddo 00261 enddo 00262 ! wwvv dcdx(nx:1,:) is still untouched, correct this ofr the parallel case 00263 cu(s%nx+1,:) = cc(s%nx+1,:) !Robert 00264 ! wwvv fix this in parallel case 00265 ! wwvv in parallel version, there will be a discrepancy between the values 00266 ! of dzbdx(nx+1,:). 00267 !wwvv so fix that 00268 ! 00269 Sus = 0.d0 00270 Sub = 0.d0 00271 ! 00272 ! suspended load, Lodewijk: no bed slope effect (yet) 00273 Sus=par%sus*(cu*s%ureps*s%hu-s%Dc*s%hu*s%dcsdx)*s%wetu 00274 ! bed load, Lodewijk: no bed slope effect (yet) 00275 Sub=par%bed*(cub*s%urepb*s%hu)*s%wetu 00276 ! 00277 ! 00278 ! Y-direction 00279 ! 00280 ! Jaap: get ua in v points and split out in u and v direction 00281 if (s%ny>0) then 00282 uau(:,1:s%ny) = 0.5*(s%ua(:,1:s%ny)*costhm(:,1:s%ny)+s%ua(:,2:s%ny+1)*costhm(:,1:s%ny)) 00283 uav(:,1:s%ny) = 0.5*(s%ua(:,1:s%ny)*sinthm(:,1:s%ny)+s%ua(:,2:s%ny+1)*sinthm(:,1:s%ny)) 00284 uau(:,s%ny+1) = uau(:,s%ny) ! Jaap 00285 uav(:,s%ny+1) = uav(:,s%ny) ! Jaap 00286 if (par%nz>1) then 00287 vev_sed(:,1:s%ny) = 0.5*(s%ve_sed(:,1:s%ny)+s%ve_sed(:,2:s%ny+1)) 00288 else 00289 vev_sed=s%vev 00290 endif 00291 uev_sed(:,1:s%ny) = 0.5*(s%ue_sed(:,1:s%ny)+s%ue_sed(:,2:s%ny+1)) 00292 if (xmpi_isright) then 00293 uev_sed(:,1:s%ny+1) = uev_sed(:,1:s%ny) 00294 endif 00295 else 00296 uau=s%ua*costhm 00297 uav=s%ua*sinthm 00298 uev_sed=s%ue_sed 00299 vev_sed=s%ve_sed 00300 endif 00301 ! Jaap: compute vmagv including ua 00302 ! s%vmagv = sqrt((s%uv+uau)**2+(s%vv+uav)**2) 00303 s%vmagv = sqrt((uev_sed+uau)**2+(vev_sed+uav)**2) 00304 ! sediment advection velocity for suspended load and bed load respectively 00305 ! REMARK: when vreps does not equal vv; no mass conservation 00306 ! s%vreps = s%vev+uav 00307 ! s%vrepb = s%vev+uav ! RJ maybe reduce this velocity? Should be s%vv instead of s%vev? 00308 s%vreps = vev_sed+uav 00309 s%vrepb = vev_sed+uav ! RJ maybe reduce this velocity? Should be s%vv instead of s%vev? 00310 ! 00311 if (s%ny>0) then 00312 do j=1,s%ny 00313 do i=1,s%nx+1 00314 if(s%vreps(i,j)>0) then 00315 cv(i,j)=par%thetanum*cc(i,j)+(1.d0-par%thetanum)*cc(i,min(j+1,s%ny)) 00316 cvb(i,j)=par%thetanum*s%pbbed(i,j,1,jg)*s%ceqbg(i,j,jg)+(1.d0-par%thetanum)& 00317 *s%pbbed(i,min(j+1,s%ny),1,jg)*s%ceqbg(i,min(j+1,s%ny),jg) 00318 !cvb(i,j)=par%thetanum*ccb(i,j)+(1.d0-par%thetanum)*ccb(i,min(j+1,ny)) 00319 elseif(s%vreps(i,j)<0) then 00320 cv(i,j)=par%thetanum*cc(i,j+1)+(1.d0-par%thetanum)*cc(i,max(j,2)) 00321 cvb(i,j)=par%thetanum*s%pbbed(i,j+1,1,jg)*s%ceqbg(i,j+1,jg)+(1.d0-par%thetanum)& 00322 *s%pbbed(i,max(j,2),1,jg)*s%ceqbg(i,max(j,2),jg) 00323 !cvb(i,j)=par%thetanum*ccb(i,j+1)+(1.d0-par%thetanum)*ccb(i,max(j,2)) 00324 else 00325 cv(i,j)=0.5d0*(cc(i,j)+cc(i,j+1)) !Jaap: cc instead of cv 00326 cvb(i,j)=0.5d0*(s%pbbed(i,j,1,jg)*s%ceqbg(i,j,jg)+s%pbbed(i,j+1,1,jg)*s%ceqbg(i,j+1,jg)) 00327 !cvb(i,j)=0.5d0*(ccb(i,j)+ccb(i,j+1)) 00328 end if 00329 s%dcsdy(i,j)=(cc(i,j+1)-cc(i,j))/s%dnv(i,j) !Jaap 00330 00331 end do 00332 end do 00333 ! wwvv dcdy(:,ny+1) is not filled in, so in parallel case: 00334 cv(:,s%ny+1) = cc(:,s%ny+1) !Robert 00335 ! wwvv in parallel version, there will be a discrepancy between the values 00336 ! of dzbdy(:,ny+1). 00337 ! wwvv so fix that 00338 else 00339 cv = cc 00340 cvb = s%ceqbg(:,:,jg) 00341 endif ! s%ny>0 00342 ! 00343 ! Compute sedimnent transport in v-direction 00344 ! 00345 Svs = 0.d0 00346 Svb = 0.d0 00347 ! Suspended load 00348 Svs=par%sus*(cv*s%vreps*s%hv-s%Dc*s%hv*s%dcsdy)*s%wetv 00349 ! Bed load 00350 Svb=par%bed*(cvb*s%vrepb*s%hv)*s%wetv 00351 ! 00352 ! 00353 ! Bed slope effects and bermslope model 00354 ! 00355 ! Where bermslope model should run 00356 if (par%bermslopetransport==1) then ! only update from false if bermslope model is used 00357 if (par%wavemodel == WAVEMODEL_SURFBEAT) then 00358 where (s%H/s%hu>par%bermslopegamma .or. s%hu<par%bermslopedepth) 00359 bermslopeindex = .true. 00360 elsewhere 00361 bermslopeindex = .false. 00362 endwhere 00363 else 00364 where (s%hu<par%bermslopedepth) 00365 bermslopeindex = .true. 00366 elsewhere 00367 bermslopeindex = .false. 00368 endwhere 00369 endif 00370 if(par%bermslopebed==1) then ! only update from false if used 00371 bermslopeindexbed = bermslopeindex 00372 endif 00373 if(par%bermslopesus==1) then ! only update from false if used 00374 bermslopeindexsus = bermslopeindex 00375 endif 00376 endif 00377 ! 00378 ! 00379 ! Do bermslope transports in bermslope locations [separated from previous to reduce block size] 00380 where(bermslopeindexbed) 00381 Sub = Sub-par%bed*(par%bermslopefac*cub*s%vmagu*s%hu*(s%dzbdx-par%bermslope))*s%wetu 00382 endwhere 00383 where(bermslopeindexsus) 00384 Sus = Sus-par%sus*(par%bermslopefac* cu*s%vmagu*s%hu*(s%dzbdx-par%bermslope))*s%wetu 00385 endwhere 00386 ! 00387 ! 00388 ! Do regular bed slope effects in other locations 00389 if (par%bdslpeffmag == BDSLPEFFMAG_ROELV_TOTAL) then 00390 where(.not. bermslopeindexbed) 00391 Sub = Sub-par%bed*(par%facsl*cub*s%vmagu*s%hu*s%dzbdx)*s%wetu 00392 endwhere 00393 where (.not. bermslopeindexsus) 00394 Sus = Sus-par%sus*(par%facsl*cu*s%vmagu*s%hu*s%dzbdx)*s%wetu 00395 endwhere 00396 Svb = Svb-par%bed*(par%facsl*cvb*s%vmagv*s%hv*s%dzbdy)*s%wetv 00397 Svs = Svs-par%sus*(par%facsl*cv*s%vmagv*s%hv*s%dzbdy)*s%wetv 00398 elseif (par%bdslpeffmag == BDSLPEFFMAG_ROELV_BED) then 00399 where(.not. bermslopeindexbed) 00400 Sub = Sub-par%bed*(par%facsl*cub*s%vmagu*s%hu*s%dzbdx)*s%wetu 00401 endwhere 00402 Svb = Svb-par%bed*(par%facsl*cvb*s%vmagv*s%hv*s%dzbdy)*s%wetv 00403 elseif (par%bdslpeffmag == BDSLPEFFMAG_SOULS_TOTAL .or. par%bdslpeffmag == BDSLPEFFMAG_SOULS_BED) then 00404 ! 00405 ! Bed slope magnitude effect (as Souslby intended) and change direction transport (see Van Rijn 1993 (section 7.2.6)) 00406 ! 00407 do j=1,s%ny+1 00408 do i=1,s%nx+1 00409 if ((dabs(Sub(i,j)) > 0.000001d0) .or. (dabs(Svb(i,j)) > 0.000001d0) .and. (.not. bermslopeindexbed(i,j)) ) then 00410 Sbmtot = dsqrt( Sub(i,j)**2.d0 + Svb(i,j)**2.d0 ) 00411 dzbds = s%dzbdx(i,j)*Sub(i,j)/Sbmtot + s%dzbdy(i,j)*Svb(i,j)/Sbmtot 00412 ! dzbdn = s%dzbdx*Svb/Sbtot + s%dzbdy*Sub/Sbtot 00413 Sub(i,j) = Sub(i,j)*(1.d0 - par%facsl*dzbds) 00414 Svb(i,j) = Svb(i,j)*(1.d0 - par%facsl*dzbds) 00415 ! 00416 endif 00417 if (((dabs(Sus(i,j)) > 0.000001d0) .or. (dabs(Svs(i,j)) > 0.000001d0)) .and. (.not. bermslopeindexsus(i,j)) & 00418 .and. par%bdslpeffmag == BDSLPEFFMAG_SOULS_TOTAL) then 00419 Ssmtot = dsqrt( Sus(i,j)**2.d0 + Svs(i,j)**2.d0 ) 00420 dzbds = s%dzbdx(i,j)*Sus(i,j)/Ssmtot + s%dzbdy(i,j)*Svs(i,j)/Ssmtot 00421 ! dzbdn = s%dzbdx*Svb/Sbtot + s%dzbdy*Sub/Sbtot 00422 Sus(i,j) = Sus(i,j)*(1.d0 - par%facsl*dzbds) 00423 Svs(i,j) = Svs(i,j)*(1.d0 - par%facsl*dzbds) 00424 endif 00425 enddo 00426 enddo 00427 endif 00428 ! 00429 ! Lodewijk: modify the direction of the bed load transport based on the bed slope, see Van Rijn 1993 (section 7.2.6) 00430 if (par%bdslpeffdir == BDSLPEFFDIR_TALMON) then 00431 do j=1,s%ny+1 00432 do i=1,s%nx+1 00433 if (((dabs(s%urepb(i,j)) > 0.0001d0) .or. (dabs(s%vrepb(i,j)) > 0.0001d0)) & 00434 .and. ((dabs(s%taubx(i,j)) > 0.0001d0) .or. (dabs(s%tauby(i,j)) > 0.0001d0))) then 00435 if (s%urepb(i,j) < 0.d0) then 00436 delta_x = datan(s%vrepb(i,j)/s%urepb(i,j))+par%px ! Angle between fluid velocity vector and the s%x-axis 00437 else 00438 delta_x = datan(s%vrepb(i,j)/s%urepb(i,j)) ! Angle between fluid velocity vector and the s%x-axis 00439 endif 00440 delta = (par%rhos-par%rho)/par%rho 00441 shields = sqrt(s%taubx(i,j)**2 + s%tauby(i,j)**2)/(delta*par%rho*par%g*s%D50(jg)) 00442 ! shields = (urepb(i,j)**2.d0+vrepb(i,j)**2.d0)*s%cf(i,j)/(par%g*D50(jg)*delta) 00443 ftheta = 1.d0/(9.d0*(s%D50(jg)/s%hh(i,j))**0.3d0*sqrt(shields)) ! Talmon 00444 psi_x = datan( (dsin(delta_x)-ftheta*s%dzbdy(i,j)) / (dcos(delta_x)-ftheta*s%dzbdx(i,j)) ) 00445 psi_x = par%bdslpeffdirfac*(psi_x - delta_x)+delta_x 00446 Sbtot = dsqrt( Sub(i,j)**2.d0 + Svb(i,j)**2.d0 ) ! Magnitude of sediment transport without direction modifcation 00447 ! Decompose the sediment transport again, know with the knowledge of the direction of the sediment transport vector 00448 Sub(i,j) = Sbtot * dcos(psi_x) 00449 Svb(i,j) = Sbtot * dsin(psi_x) 00450 else 00451 Sub(i,j) = 0.d0 00452 Svb(i,j) = 0.d0 00453 endif 00454 enddo 00455 enddo 00456 endif 00457 ! 00458 ! 00459 ! 00460 do j=1,s%ny+1 00461 do i=1,s%nx 00462 if(Sub(i,j)>0.d0) then 00463 pbbedu(i,j) = s%pbbed(i,j,1,jg) 00464 elseif(Sub(i,j)<0.d0) then 00465 pbbedu(i,j)= s%pbbed(i+1,j,1,jg) 00466 else 00467 pbbedu(i,j)=0.5d0*(s%pbbed(i,j,1,jg)+s%pbbed(i+1,j,1,jg)) 00468 endif 00469 enddo 00470 enddo 00471 ! 00472 Sub = pbbedu*Sub 00473 ! 00474 do j=1,s%ny 00475 do i=1,s%nx+1 00476 if(Svb(i,j)>0) then 00477 pbbedv(i,j)=s%pbbed(i,j,1,jg) 00478 else if(Svb(i,j)<0) then 00479 pbbedv(i,j)=s%pbbed(i,j+1,1,jg) 00480 else 00481 pbbedv(i,j)=0.5d0*(s%pbbed(i,j,1,jg)+s%pbbed(i,j+1,1,jg)) 00482 end if 00483 end do 00484 end do 00485 ! 00486 Svb = pbbedv*Svb 00487 ! 00488 ! BRJ: implicit concentration update (compute sources first, sink must be computed after updating actual sed.conc.) 00489 ! 00490 if (s%ny>0) then 00491 do j=jmin_zs,jmax_zs 00492 do i=imin_zs,imax_zs 00493 ! Changed to hh from hold by RJ (13072009) !**2/max(hh(i,j),par%hmin) 00494 s%ero(i,j,jg) = fac(i,j,jg)*s%hh(i,j)*s%ceqsg(i,j,jg)*s%pbbed(i,j,1,jg)/s%Tsg(i,j,jg) 00495 ! depo_ex(i,j,jg) = max(hold(i,j),0.01d0)*cc(i,j)/Tsg(i,j,jg) 00496 ! BRJ: the volume in the water column is updated and not the volume concentration. 00497 cc(i,j) = (par%dt*s%Tsg(i,j,jg))/(par%dt+s%Tsg(i,j,jg))* & 00498 (s%hold(i,j)*cc(i,j)/par%dt -((Sus(i,j)*s%dnu(i,j)-Sus(i-1,j)*s%dnu(i-1,j)+& 00499 Svs(i,j)*s%dsv(i,j)-Svs(i,j-1)*s%dsv(i,j-1))*s%dsdnzi(i,j)-& 00500 s%ero(i,j,jg))) 00501 00502 cc(i,j)=max(cc(i,j),0.0d0) ! Jaap: negative cc's are possible... 00503 cc(i,j)=min(cc(i,j),par%cmax*s%hh(i,j)) 00504 s%depo_ex(i,j,jg) = cc(i,j)/s%Tsg(i,j,jg) 00505 enddo 00506 enddo 00507 00508 else 00509 j=1 00510 do i=imin_zs,imax_zs 00511 ! Changed to hh from hold by RJ (13072009) !**2/max(hh(i,j),par%hmin) 00512 s%ero(i,j,jg) = fac(i,j,jg)*s%hh(i,j)*s%ceqsg(i,j,jg)*s%pbbed(i,j,1,jg)/s%Tsg(i,j,jg) 00513 ! depo_ex(i,j,jg) = max(hold(i,j),0.01d0)*cc(i,j)/Tsg(i,j,jg) 00514 ! BRJ: the volume in the water column is updated and not the volume concentration. 00515 cc(i,j) = (par%dt*s%Tsg(i,j,jg))/(par%dt+s%Tsg(i,j,jg))* & 00516 (s%hold(i,j)*cc(i,j)/par%dt -((Sus(i,j)*s%dnu(i,j)-Sus(i-1,j)*s%dnu(i-1,j))*s%dsdnzi(i,j)-& 00517 s%ero(i,j,jg))) 00518 00519 cc(i,j)=max(cc(i,j),0.0d0) ! Jaap: negative cc's are possible... 00520 cc(i,j)=min(cc(i,j),par%cmax*s%hh(i,j)) 00521 00522 s%depo_ex(i,j,jg) = cc(i,j)/s%Tsg(i,j,jg) 00523 enddo 00524 endif 00525 00526 00527 cc(imin_zs:imax_zs,jmin_zs:jmax_zs) = cc(imin_zs:imax_zs,jmin_zs:jmax_zs)/s%hh(imin_zs:imax_zs,jmin_zs:jmax_zs) 00528 00529 ! do lateral boundaries... 00530 if(xmpi_istop)then 00531 cc(1,:)=cc(2,:) 00532 s%ero(1,:,jg)=s%ero(2,:,jg) 00533 s%depo_ex(1,:,jg)=s%depo_ex(2,:,jg) 00534 endif 00535 if(xmpi_isleft .and. s%ny>0)then 00536 cc(:,1)=cc(:,2) 00537 s%ero(:,1,jg)=s%ero(:,2,jg) 00538 s%depo_ex(:,1,jg)=s%depo_ex(:,2,jg) 00539 endif 00540 if(xmpi_isbot)then 00541 cc(s%nx+1,:)=cc(s%nx,:) 00542 s%ero(s%nx+1,:,jg)=s%ero(s%nx,:,jg) 00543 s%depo_ex(s%nx+1,:,jg)=s%depo_ex(s%nx,:,jg) 00544 endif 00545 if(xmpi_isright .and. s%ny>0)then 00546 cc(:,s%ny+1)=cc(:,s%ny) 00547 s%ero(:,s%ny+1,jg)=s%ero(:,s%ny,jg) 00548 s%depo_ex(:,s%ny+1,jg)=s%depo_ex(:,s%ny,jg) 00549 endif 00550 ! Dano: fix nasty numerics 00551 where (cc<1.d-10) 00552 cc=0.d0 00553 endwhere 00554 ! wwvv fix the first and last rows and columns of cc in parallel case 00555 #ifdef USEMPI 00556 call xmpi_shift_ee(cc) 00557 #endif 00558 ! wwvv border columns and rows of ccg Svg and Sug have to be communicated 00559 ! 00560 ! An additional sensitivity to D50 (called par%alfaD50) 00561 ! By default par%alfaD50 = 0, so no additional sensitivity 00562 if (par%alfaD50 > 0) then 00563 do j=1,s%ny+1 00564 do i=1,s%nx+1 00565 Svs(i,j) = Svs(i,j) * (0.000225/par%D50(jg))**par%alfaD50 00566 Sus(i,j) = Sus(i,j) * (0.000225/par%D50(jg))**par%alfaD50 00567 Svb(i,j) = Svb(i,j) * (0.000225/par%D50(jg))**par%alfaD50 00568 Sub(i,j) = Sub(i,j) * (0.000225/par%D50(jg))**par%alfaD50 00569 enddo 00570 enddo 00571 endif 00572 00573 ! Save concentrations and sediment transport in s 00574 s%ccg(:,:,jg) = cc 00575 s%Svsg(:,:,jg) = Svs 00576 s%Susg(:,:,jg) = Sus 00577 s%Svbg(:,:,jg) = Svb 00578 s%Subg(:,:,jg) = Sub 00579 00580 end do ! number of sediment fractions 00581 00582 s%vmag=sqrt(max(vmag2,par%umin)) 00583 00584 end subroutine transus 00585 00586 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00587 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00588 00589 subroutine bed_update(s,par) 00590 use params, only: parameters 00591 use spaceparamsdef 00592 use spaceparams 00593 use xmpi_module 00594 00595 implicit none 00596 00597 type(spacepars),target :: s 00598 type(parameters) :: par 00599 00600 integer :: i,j,j1,jg,ii,ie,id,je,jd,jdz,ndz, hinterland 00601 integer , dimension(:,:,:),allocatable,save :: indSus,indSub,indSvs,indSvb 00602 real*8 :: dzb,dzmax,dzt,dzleft,sdz,dzavt,fac,Savailable,dAfac 00603 real*8 , dimension(:,:),allocatable,save :: Sout,hav,tempexchange 00604 real*8 , dimension(par%ngd) :: edg,edg1,edg2,dzg 00605 real*8 , dimension(:),pointer :: dz 00606 real*8 , dimension(:,:),pointer :: pb 00607 integer :: n_aval,im1,ip1,jm1,jp1 00608 real*8,save :: delta 00609 real*8 :: totslp 00610 00611 !include 's.ind' 00612 !include 's.inp' 00613 00614 if (.not. allocated(Sout)) then 00615 allocate(Sout(s%nx+1,s%ny+1)) 00616 allocate(hav(s%nx+1,s%ny+1)) 00617 allocate(indSus(s%nx+1,s%ny+1,par%ngd)) 00618 allocate(indSub(s%nx+1,s%ny+1,par%ngd)) 00619 allocate(indSvs(s%nx+1,s%ny+1,par%ngd)) 00620 allocate(indSvb(s%nx+1,s%ny+1,par%ngd)) 00621 if (par%gwflow==1) then 00622 allocate(tempexchange(s%nx+1,s%ny+1)) 00623 endif 00624 delta = (par%rhos-par%rho)/par%rho 00625 endif 00626 00627 ! Super fast 1D 00628 if (s%ny==0) then 00629 j1 = 1 00630 else 00631 j1 = 2 00632 endif 00633 s%dzbnow = 0.d0 00634 dzb = 0.d0 00635 if (par%t>=par%morstart .and. par%t < par%morstop .and. par%morfac > .999d0) then 00636 ! 00637 ! bed_predict 00638 ! 00639 ! reduce sediment transports when hard layer comes to surface 00640 ! this step is mainly necessary at the transition from hard layers to sand 00641 if (par%struct == 1) then 00642 00643 do jg = 1,par%ngd 00644 indSus = 0 00645 indSub = 0 00646 indSvs = 0 00647 indSvb = 0 00648 Sout = 0.d0 00649 do j=j1,s%ny+1 00650 do i=2,s%nx+1 00651 ! fluxes at i,j 00652 if (s%Subg(i,j,jg) > 0.d0) then ! bed load s%u-direction 00653 indSub(i,j,jg) = 1 00654 Sout(i,j) = Sout(i,j) + s%Subg(i,j,jg)*s%dnu(i,j) 00655 endif 00656 ! fluxes at i-1,j 00657 if (s%Subg(i-1,j,jg) < 0.d0 ) then ! bed load s%u-direction 00658 Sout(i,j) = Sout(i,j) - s%Subg(i-1,j,jg)*s%dnu(i-1,j) 00659 endif 00660 if (par%sourcesink==0) then 00661 ! fluxes at i,j 00662 if (s%Susg(i,j,jg) > 0.d0 ) then ! suspended load s%u-direction 00663 indSus(i,j,jg) = 1 00664 Sout(i,j) = Sout(i,j) + s%Susg(i,j,jg)*s%dnu(i,j) 00665 endif 00666 ! fluxes at i-1,j 00667 if (s%Susg(i-1,j,jg) < 0.d0 ) then ! suspended load s%u-direction 00668 Sout(i,j) = Sout(i,j) - s%Susg(i-1,j,jg)*s%dnu(i-1,j) 00669 endif 00670 endif 00671 enddo 00672 enddo 00673 if (s%ny>0) then 00674 do j=j1,s%ny+1 00675 do i=2,s%nx+1 00676 if (s%Svbg(i,j,jg) > 0.d0 ) then ! bed load s%v-direction 00677 indSvb(i,j,jg) = 1 00678 Sout(i,j) = Sout(i,j) + s%Svbg(i,j,jg)*s%dsv(i,j) 00679 endif 00680 ! fluxes at i,j-1 00681 if (s%Svbg(i,j-1,jg) < 0.d0 ) then ! bed load s%v-direction 00682 Sout(i,j) = Sout(i,j) - s%Svbg(i,j-1,jg)*s%dsv(i,j-1) 00683 endif 00684 if (par%sourcesink==0) then 00685 if (s%Svsg(i,j,jg) > 0.d0 ) then ! suspended load s%v-direction 00686 indSvs(i,j,jg) = 1 00687 Sout(i,j) = Sout(i,j) + s%Svsg(i,j,jg)*s%dsv(i,j) 00688 endif 00689 ! fluxes at i,j-1 00690 if (s%Svsg(i,j-1,jg) < 0.d0 ) then ! suspended load s%v-direction 00691 Sout(i,j) = Sout(i,j) - s%Svsg(i,j-1,jg)*s%dsv(i,j-1) 00692 endif 00693 endif ! sourcesink = 0 00694 enddo !s%nx+1 00695 enddo !s%ny+1 00696 endif !s%ny>0 00697 ! 00698 do j=j1,s%ny+1 00699 do i=2,s%nx+1 00700 Savailable = s%structdepth(i,j)*s%pbbed(i,j,1,jg)/par%morfac/par%dt*(1.d0-par%por)/s%dsdnzi(i,j) 00701 ! reduction factor for cell outgoing sediment transports wwvv changed tiny into epsilon 00702 fac = min(1.d0,Savailable/max(Sout(i,j),epsilon(0.d0)) ) 00703 ! fix sediment transports for the presence of a hard layer; remind indSus etc are 1 in cases of cell outgoing transports 00704 ! updated S oell outgoing transports cell incoming transports 00705 if (fac < 1.d0)then 00706 s%Subg(i,j,jg) = fac*indSub(i,j,jg)*s%Subg(i,j,jg) + (1-indSub(i,j,jg))*s%Subg(i,j,jg) 00707 s%Subg(i-1,j,jg) = fac*(1-indSub(i-1,j,jg))*s%Subg(i-1,j,jg) + indSub(i-1,j,jg)*s%Subg(i-1,j,jg) 00708 if (s%ny>0) then 00709 s%Svbg(i,j,jg) = fac*indSvb(i,j,jg)*s%Svbg(i,j,jg) + (1-indSvb(i,j,jg))*s%Svbg(i,j,jg) 00710 s%Svbg(i,j-1,jg) = fac*(1-indSvb(i,j-1,jg))*s%Svbg(i,j-1,jg) + indSvb(i,j-1,jg)*s%Svbg(i,j-1,jg) 00711 endif 00712 if (par%sourcesink==0) then 00713 s%Susg(i,j,jg) = fac*indSus(i,j,jg)*s%Susg(i,j,jg) + (1-indSus(i,j,jg))*s%Susg(i,j,jg) 00714 s%Susg(i-1,j,jg) = fac*(1-indSus(i-1,j,jg))*s%Susg(i-1,j,jg) + indSus(i-1,j,jg)*s%Susg(i-1,j,jg) 00715 if (s%ny>0) then 00716 s%Svsg(i,j,jg) = fac*indSvs(i,j,jg)*s%Svsg(i,j,jg) + (1-indSvs(i,j,jg))*s%Svsg(i,j,jg) 00717 s%Svsg(i,j-1,jg) = fac*(1-indSvs(i,j-1,jg))*s%Svsg(i,j-1,jg) + indSvs(i,j-1,jg)*s%Svsg(i,j-1,jg) 00718 endif !s%ny = 0 00719 endif ! sourcesink = 0 00720 endif !fac<1.d0 00721 enddo ! s%nx+1 00722 enddo !s%ny + 1 00723 enddo !par%ngd 00724 endif !struct == 1 00725 00726 if (s%ny>0) then 00727 do j=jmin_zs,jmax_zs 00728 do i=imin_zs,imax_zs 00729 00730 ! bed level changes per fraction in this morphological time step in meters sand including pores 00731 ! positive in case of erosion 00732 if (par%sourcesink==0) then 00733 dzg=par%morfac*par%dt/(1.d0-par%por)*( & ! Dano, dz from sus transport gradients 00734 ( s%Susg(i,j,:)*s%dnu(i,j)-s%Susg(i-1,j,:)*s%dnu(i-1,j) +& 00735 s%Svsg(i,j,:)*s%dsv(i,j)-s%Svsg(i,j-1,:)*s%dsv(i,j-1) +& 00736 ! dz from bed load transport gradients 00737 s%Subg(i,j,:)*s%dnu(i,j)-s%Subg(i-1,j,:)*s%dnu(i-1,j)+& 00738 s%Svbg(i,j,:)*s%dsv(i,j)-s%Svbg(i,j-1,:)*s%dsv(i,j-1) )*s%dsdnzi(i,j) ) 00739 elseif (par%sourcesink==1) then 00740 dzg=par%morfac*par%dt/(1.d0-par%por)*( & 00741 s%ero(i,j,:)-s%depo_ex(i,j,:) +& 00742 ( s%Subg(i,j,:)*s%dnu(i,j)-s%Subg(i-1,j,:)*s%dnu(i-1,j)+& 00743 s%Svbg(i,j,:)*s%dsv(i,j)-s%Svbg(i,j-1,:)*s%dsv(i,j-1) )*s%dsdnzi(i,j) ) 00744 endif 00745 00746 if (par%ngd==1) then ! Simple bed update in case one fraction 00747 00748 s%zb(i,j) = s%zb(i,j)-sum(dzg) 00749 s%dzbnow(i,j) = s%dzbnow(i,j)-sum(dzg) ! naamgeveing? 00750 s%dzbdt(i,j) = s%dzbnow(i,j)/par%dt 00751 s%sedero(i,j) = s%sedero(i,j)-sum(dzg) 00752 s%structdepth(i,j) = max(0.d0,s%structdepth(i,j)-sum(dzg)) 00753 00754 else 00755 ! erosion/deposition rate of sand mass (m/s) 00756 ! positive in case of erosion 00757 edg = dzg*(1.d0-par%por)/par%dt 00758 00759 00760 dz=>s%dzbed(i,j,:) 00761 pb=>s%pbbed(i,j,:,:) 00762 00763 call update_fractions(par,s,i,j,dz,pb,edg,sum(dzg)) 00764 00765 endif 00766 00767 enddo ! s%nx+1 00768 enddo ! s%ny+1 00769 else 00770 j=1 00771 do i=imin_zs,imax_zs 00772 ! bed level changes per fraction in this morphological time step in meters sand including pores 00773 ! positive in case of erosion 00774 if (par%sourcesink==0) then 00775 dzg=par%morfac*par%dt/(1.d0-par%por)*( & ! Dano, dz from sus transport gradients 00776 ( s%Susg(i,j,:)*s%dnu(i,j)-s%Susg(i-1,j,:)*s%dnu(i-1,j) +& 00777 s%Subg(i,j,:)*s%dnu(i,j)-s%Subg(i-1,j,:)*s%dnu(i-1,j) )*s%dsdnzi(i,j) +& 00778 (s%Svsg(i,j,:)+s%Svbg(i,j,:))*par%lsgrad) 00779 elseif (par%sourcesink==1) then 00780 dzg=par%morfac*par%dt/(1.d0-par%por)*( & 00781 s%ero(i,j,:)-s%depo_ex(i,j,:) +& 00782 ( s%Subg(i,j,:)*s%dnu(i,j)-s%Subg(i-1,j,:)*s%dnu(i-1,j) )*s%dsdnzi(i,j) +& 00783 (s%Svsg(i,j,:)+s%Svbg(i,j,:))*par%lsgrad) 00784 endif 00785 00786 if (par%ngd==1) then ! Simple bed update in case one fraction 00787 00788 s%zb(i,j) = s%zb(i,j)-sum(dzg) 00789 s%dzbnow(i,j) = s%dzbnow(i,j)-sum(dzg) 00790 s%dzbdt(i,j) = s%dzbnow(i,j)/par%dt 00791 s%sedero(i,j) = s%sedero(i,j)-sum(dzg) 00792 s%structdepth(i,j) = max(0.d0,s%structdepth(i,j)-sum(dzg)) 00793 00794 else ! multiple fractions... 00795 ! erosion/deposition rate of sand mass (m/s) 00796 ! positive in case of erosion 00797 edg = dzg*(1.d0-par%por)/par%dt 00798 00799 dz=>s%dzbed(i,j,:) 00800 pb=>s%pbbed(i,j,:,:) 00801 00802 call update_fractions(par,s,i,j,dz,pb,edg,sum(dzg)) 00803 00804 endif 00805 00806 enddo ! s%nx+1 00807 endif !s%ny>0 00808 #ifdef USEMPI 00809 call xmpi_shift_ee(s%zb) 00810 call xmpi_shift_ee(s%structdepth) 00811 #endif 00812 ! In case of groundwater, we need to update groundwater levels and surface water 00813 if(par%gwflow==1) then 00814 where (s%wetz==1 .and. s%dzbnow>0.d0) ! accretion in wet areas 00815 s%zs = s%zs + s%dzbnow*(1.d0-par%por) ! zs = zs + dzbnow - dzbnow*par%por 00816 s%gwlevel = s%gwlevel+s%dzbnow 00817 s%infil = s%infil + s%dzbnow*par%por/par%dt 00818 elsewhere (s%wetz==1 .and. s%dzbnow<0.d0) ! erosion in wet areas 00819 ! maximum water leaving groundwater = gwlevel(not updated) - zb(updated) 00820 ! note that exfiltration is negative infil 00821 tempexchange = min((s%zb-s%gwlevel)*par%por,0.d0) 00822 s%zs = s%zs + s%dzbnow - tempexchange 00823 s%gwlevel = s%gwlevel + tempexchange/par%por 00824 s%infil = s%infil + tempexchange 00825 endwhere 00826 #ifdef USEMPI 00827 call xmpi_shift_ee(s%gwlevel) 00828 call xmpi_shift_ee(s%infil) 00829 call xmpi_shift_ee(s%zs) 00830 #endif 00831 else ! only need to update water levels 00832 where (s%wetz(imin_zs:imax_zs,jmin_zs:jmax_zs)==1) 00833 s%zs(imin_zs:imax_zs,jmin_zs:jmax_zs) = s%zs(imin_zs:imax_zs,jmin_zs:jmax_zs)+s%dzbnow(imin_zs:imax_zs,jmin_zs:jmax_zs) 00834 endwhere 00835 #ifdef USEMPI 00836 call xmpi_shift_ee(s%zs) 00837 #endif 00838 endif 00839 00840 00841 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00842 ! 00843 ! Avalanching 00844 ! 00845 00846 00847 if (par%avalanching==1) then 00848 00849 if(par%fixedavaltime==0) then 00850 par%avaltime = par%nTrepavaltime*par%Trep 00851 endif 00852 00853 do ii=1,nint(par%morfac) 00854 !aval=.false. 00855 n_aval=0 !Dano fix for MPI 00856 do j=1,s%ny+1 00857 do i=1,s%nx 00858 s%dzbdx(i,j)=(s%zb(i+1,j)-s%zb(i,j))/s%dsu(i,j) 00859 enddo 00860 s%dzbdx(s%nx+1,j)=s%dzbdx(s%nx,j) 00861 enddo 00862 do j=1,s%ny 00863 do i=1,s%nx+1 00864 s%dzbdy(i,j)=(s%zb(i,j+1)-s%zb(i,j))/s%dnv(i,j) 00865 enddo 00866 enddo 00867 if (s%ny>0) then 00868 do i=1,s%nx+1 00869 s%dzbdy(i,s%ny+1)=s%dzbdy(i,s%ny) 00870 enddo 00871 endif 00872 ! 00873 hav = s%hh 00874 ! Fix Hav for short wave runup: 00875 if (par%swrunup == 1) then 00876 do j = 1,s%ny+1 00877 hinterland = 0 00878 do i = 1, s%nx+1 00879 if (hinterland == 0 .and. s%runup(j)+s%zs(nint(s%iwl(j)),j) < s%zb(i,j) + par%eps) then 00880 hinterland = 1; 00881 endif 00882 if (s%wetz(i,j) == 1) then 00883 hav(i,j) = max(par%eps,(s%hh(i,j) + s%runup(j))) 00884 elseif (hinterland == 0) then 00885 hav(i,j) = max(par%eps,s%runup(j)+s%zs(nint(s%iwl(j)),j)-s%zb(i,j) ) 00886 else 00887 hav(i,j) = par%eps; 00888 endif 00889 enddo 00890 enddo 00891 endif 00892 ! 00893 do i=2,s%nx !-1 Jaap -1 gives issues for bed updating at mpi boundaries 00894 do j=1,s%ny+1 00895 !if (max( max(hh(i,j),par%delta*H(i,j)), max(hh(i+1,j),par%delta*H(i+1,j)) )>par%hswitch+par%eps) then 00896 ip1=min(i+1,s%nx+1) 00897 jm1=max(j-1,1) 00898 totslp=sqrt(s%dzbdx(i,j)**2+(.25*(s%dzbdy(i,j)+s%dzbdy(ip1,j)+s%dzbdy(i,jm1)+s%dzbdy(ip1,jm1)))**2) 00899 if(max(hav(i,j),hav(i+1,j))>par%hswitch+par%eps) then ! Jaap instead of s%hh 00900 dzmax=par%wetslp*abs(s%dzbdx(i,j))/totslp 00901 ! tricks: seaward of istruct (transition from sand to structure) wetslope is set to 0.03; 00902 if (i>nint(s%istruct(j))) then 00903 !dzmax = 0.03d0 00904 dzmax = max(0.03d0,abs(s%dzbdx(i,j))*0.99d0) 00905 endif 00906 else 00907 dzmax=par%dryslp*abs(s%dzbdx(i,j))/totslp 00908 end if 00909 00910 if(abs(s%dzbdx(i,j))>dzmax+1.d-10 .and. s%structdepth(i+nint(max(0.d0,sign(1.d0,s%dzbdx(i,j)))),j)>par%eps) then 00911 n_aval=n_aval+1 00912 dzb=sign(1.0d0,s%dzbdx(i,j))*(abs(s%dzbdx(i,j))-dzmax)*s%dsu(i,j) 00913 00914 if (dzb >= 0.d0) then 00915 ie = i+1 ! index erosion point 00916 id = i ! index deposition point 00917 dAfac = s%dsdnzi(i,j)/s%dsdnzi(i+1,j) ! take into account varying grid sizes 00918 !dzb=min(dzb,par%dzmax*par%dt/s%dsu(i,j)) ! make sure dzb is not in conflict with par%dzmax 00919 dzb=dzb/par%avaltime*par%dt ! Dano more transparent formulation, removes direction dependence 00920 dzb=min(dzb,s%structdepth(i+1,j)) ! make sure dzb is not larger than sediment layer thickness 00921 else 00922 ie = i ! index erosion point 00923 id = i+1 ! index deposition point 00924 dAfac = s%dsdnzi(i+1,j)/s%dsdnzi(i,j) ! take into account varying grid sizes 00925 !dzb=max(dzb,-par%dzmax*par%dt/s%dsu(i,j)) 00926 dzb=dzb/par%avaltime*par%dt ! Dano more transparent formulation, removes direction dependence 00927 dzb=max(dzb,-s%structdepth(i,j)) 00928 endif 00929 00930 00931 if (par%ngd == 1) then ! Simple bed update in case one fraction 00932 00933 dzleft = abs(dzb) 00934 00935 s%zb(id,j) = s%zb(id,j)+dzleft*dAfac 00936 s%zb(ie,j) = s%zb(ie,j)-dzleft 00937 s%dzbnow(id,j) = s%dzbnow(id,j)+dzleft*dAfac ! naamgeveing? 00938 s%dzbnow(ie,j) = s%dzbnow(ie,j)-dzleft 00939 s%sedero(id,j) = s%sedero(id,j)+dzleft*dAfac 00940 s%sedero(ie,j) = s%sedero(ie,j)-dzleft 00941 s%structdepth(id,j) = max(0.d0,s%structdepth(id,j)+dzleft*dAfac) 00942 s%structdepth(ie,j) = max(0.d0,s%structdepth(ie,j)-dzleft) 00943 00944 s%zs(id,j) = s%zs(id,j)+dzleft*dAfac 00945 s%zs(ie,j) = s%zs(ie,j)-dzleft 00946 s%dzav(id,j)= s%dzav(id,j)+dzleft*dAfac 00947 s%dzav(ie,j)= s%dzav(ie,j)-dzleft 00948 00949 else ! multiple fractions... 00950 00951 ! now fix fractions.... 00952 dz => s%dzbed(ie,j,:) 00953 pb => s%pbbed(ie,j,:,:) 00954 00955 ! figure out how many depth layers (ndz) are eroded in point iii 00956 sdz = 0 00957 ndz = 0 00958 do while (sdz<abs(dzb)) 00959 ndz = ndz+1 00960 sdz = sdz+dz(ndz) 00961 enddo 00962 00963 ! now update bed and fractions by stepping through each layer seperately 00964 dzleft = abs(dzb) 00965 dzavt = 0.d0 00966 00967 do jdz=1,ndz 00968 00969 dzt = min(dz(jdz),dzleft) 00970 dzleft = dzleft-dzt; 00971 00972 ! erosion deposition per fraction (upwind or downwind); edg is positive in case of erosion 00973 do jg=1,par%ngd 00974 edg2(jg) = s%sedcal(jg)*dzt*pb(jdz,jg)*(1.d0-par%por)/par%dt ! erosion (dzt always > 0 ) 00975 edg1(jg) = -s%sedcal(jg)*edg2(jg)*dAfac ! deposition (dzt always < 0 ) 00976 enddo 00977 00978 dzavt = dzavt + sum(edg2)*par%dt/(1.d0-par%por) 00979 00980 call update_fractions(par,s,ie,j,s%dzbed(ie,j,:),s%pbbed(ie,j,:,:),edg2,dzavt) ! update bed in eroding point 00981 00982 call update_fractions(par,s,id,j,s%dzbed(id,j,:),s%pbbed(id,j,:,:),edg1,-dzavt*dAfac) ! update bed in deposition point 00983 00984 enddo 00985 00986 ! update water levels and dzav 00987 s%zs(ie,j) = s%zs(ie,j)-dzavt 00988 s%dzav(ie,j)= s%dzav(ie,j)-dzavt 00989 00990 s%zs(id,j) = s%zs(id,j)+dzavt*dAfac 00991 s%dzav(id,j)= s%dzav(id,j)+dzavt*dAfac 00992 00993 end if ! yes/no multiple fractions 00994 end if 00995 end do 00996 end do 00997 !Dano: computed earlier 00998 !do j=1,s%ny 00999 ! do i=1,s%nx+1 01000 ! s%dzbdy(i,j)=(s%zb(i,j+1)-s%zb(i,j))/s%dnv(i,j) 01001 ! enddo 01002 !enddo 01003 01004 do j=2,s%ny !-1 Jaap -1 gives issues for bed updating at mpi boundaries 01005 do i=1,s%nx+1 01006 jp1=min(j+1,s%ny+1) 01007 im1=max(i-1,1) 01008 totslp=sqrt(s%dzbdy(i,j)**2+(.25*(s%dzbdx(i,j)+s%dzbdx(i,jp1)+s%dzbdx(im1,j)+s%dzbdx(im1,jp1)))**2) 01009 01010 if(max(s%hh(i,j),s%hh(i,j+1))>par%hswitch+par%eps) then 01011 dzmax=par%wetslp*abs(s%dzbdy(i,j))/totslp 01012 else 01013 dzmax=par%dryslp*abs(s%dzbdy(i,j))/totslp 01014 end if 01015 if(abs(s%dzbdy(i,j))>dzmax .and. s%structdepth(i,j+nint(max(0.d0,sign(1.d0,s%dzbdy(i,j)))))>par%eps) then ! Jaap 01016 n_aval=n_aval+1 01017 dzb=sign(1.0d0,s%dzbdy(i,j))*(abs(s%dzbdy(i,j))-dzmax)*s%dnv(i,j) 01018 ! 01019 if (dzb >= 0.d0) then 01020 je = j+1 ! index erosion point 01021 jd = j ! index deposition point 01022 dAfac = s%dsdnzi(i,j)/s%dsdnzi(i,j+1) ! take into account varying grid sizes 01023 !dzb=min(dzb,par%dzmax*par%dt/s%dnv(i,j)) 01024 dzb=dzb/par%avaltime*par%dt ! Dano 01025 dzb=min(dzb,s%structdepth(i,j+1)) 01026 else 01027 je = j ! index erosion point 01028 jd = j+1 ! index deposition point 01029 dAfac = s%dsdnzi(i,j+1)/s%dsdnzi(i,j) ! take into account varying grid sizes 01030 !dzb=max(dzb,-par%dzmax*par%dt/s%dnv(i,j)) 01031 dzb=dzb/par%avaltime*par%dt ! Dano 01032 dzb=max(dzb,-s%structdepth(i,j)) 01033 endif 01034 01035 if (par%ngd == 1) then ! Simple bed update in case one fraction 01036 01037 dzleft = abs(dzb) 01038 01039 s%zb(i,jd) = s%zb(i,jd)+dzleft*dAfac 01040 s%zb(i,je) = s%zb(i,je)-dzleft 01041 s%dzbnow(i,jd) = s%dzbnow(i,jd)+dzleft*dAfac ! naamgeveing? 01042 s%dzbnow(i,je) = s%dzbnow(i,je)-dzleft 01043 s%sedero(i,jd) = s%sedero(i,jd)+dzleft*dAfac 01044 s%sedero(i,je) = s%sedero(i,je)-dzleft 01045 s%structdepth(i,jd) = max(0.d0,s%structdepth(i,jd)+dzleft*dAfac) 01046 s%structdepth(i,je) = max(0.d0,s%structdepth(i,je)-dzleft) 01047 01048 s%zs(i,jd) = s%zs(i,jd)+dzleft*dAfac 01049 s%zs(i,je) = s%zs(i,je)-dzleft 01050 s%dzav(i,jd)= s%dzav(i,jd)+dzleft*dAfac 01051 s%dzav(i,je)= s%dzav(i,je)-dzleft 01052 01053 else ! multiple fractions... 01054 01055 dz => s%dzbed(i,je,:) 01056 pb => s%pbbed(i,je,:,:) 01057 01058 ! figure out how many depth layers (ndz) are affected 01059 sdz = 0 01060 ndz = 0 01061 do while (sdz<abs(dzb)) 01062 ndz = ndz+1 01063 sdz = sdz+dz(ndz) 01064 enddo 01065 01066 ! now update bed and fractions by stepping through each layer seperately 01067 dzleft = abs(dzb) 01068 dzavt = 0.d0 01069 01070 do jdz=1,ndz 01071 dzt = min(dz(jdz),dzleft) 01072 dzleft = dzleft-dzt; 01073 01074 ! erosion deposition per fraction (upwind or downwind); edg is positive in case of erosion 01075 do jg=1,par%ngd 01076 edg2(jg) = s%sedcal(jg)*dzt*pb(jdz,jg)*(1.d0-par%por)/par%dt ! erosion (dzt always > 0 ) 01077 edg1(jg) = -s%sedcal(jg)*edg2(jg)*dAfac ! deposition (dzt always < 0 ) 01078 enddo 01079 01080 dzavt = dzavt + sum(edg2)*par%dt/(1.d0-par%por) 01081 01082 call update_fractions(par,s,i,je,s%dzbed(i,je,:),s%pbbed(i,je,:,:),edg2,dzavt) ! upwind point 01083 01084 call update_fractions(par,s,i,jd,s%dzbed(i,jd,:),s%pbbed(i,jd,:,:),edg1,-dzavt*dAfac) ! downwind point 01085 01086 enddo 01087 01088 ! update water levels and dzav 01089 s%zs(i,je) = s%zs(i,je)-dzavt 01090 s%dzav(i,je)= s%dzav(i,je)-dzavt 01091 01092 s%zs(i,jd) = s%zs(i,jd)+dzavt*dAfac 01093 s%dzav(i,jd)= s%dzav(i,jd)+dzavt*dAfac 01094 01095 endif !yes/no multiple fractions 01096 end if 01097 end do 01098 end do 01099 ! write(*,*)'t ',par%t,'ii ',ii,' n_aval ',n_aval,' rank ',xmpi_rank 01100 ! Dano: in parallel version bed update must take place AFTER EACH ITERATION 01101 #ifdef USEMPI 01102 call xmpi_allreduce(n_aval ,MPI_SUM) 01103 #endif 01104 if (n_aval>0) then 01105 #ifdef USEMPI 01106 call xmpi_shift_ee(s%zb) 01107 call xmpi_shift_ee(s%structdepth) 01108 #endif 01109 else 01110 exit 01111 endif 01112 01113 end do 01114 else 01115 s%dzbdx=0.d0 01116 s%dzbdy=0.d0 01117 do j=1,s%ny+1 01118 do i=1,s%nx 01119 s%dzbdx(i,j)=(s%zb(i+1,j)-s%zb(i,j))/s%dsu(i,j) 01120 enddo 01121 enddo 01122 do j=1,s%ny 01123 do i=1,s%nx+1 01124 s%dzbdy(i,j)=(s%zb(i,j+1)-s%zb(i,j))/s%dnv(i,j) 01125 enddo 01126 enddo 01127 end if 01128 ! 01129 ! bed boundary conditions 01130 ! 01131 ! Dano: the following Neumann boundaries introduce a mass error equal to 01132 ! the bed level change due to the b.c. times the cell area. 01133 if(xmpi_isleft .and. s%ny>0) then 01134 s%zb(:,1) = s%zb(:,2) 01135 s%dzbdt(:,1) = s%dzbdt(:,2) 01136 s%dzbnow(:,1) = s%dzbnow(:,2) 01137 s%sedero(:,1) = s%sedero(:,2) 01138 s%structdepth(:,1) = s%structdepth(:,2) 01139 s%pbbed(:,1,:,:)=s%pbbed(:,2,:,:) 01140 s%z0bed(:,1)=s%z0bed(:,2) 01141 s%dzbed(:,1,:)=s%dzbed(:,2,:) 01142 endif 01143 01144 if(xmpi_isright .and. s%ny>0) then 01145 s%zb(:,s%ny+1) = s%zb(:,s%ny) 01146 s%dzbdt(:,s%ny+1) = s%dzbdt(:,s%ny) 01147 s%dzbnow(:,s%ny+1) = s%dzbnow(:,s%ny) 01148 s%sedero(:,s%ny+1) = s%sedero(:,s%ny) 01149 s%structdepth(:,s%ny+1) = s%structdepth(:,s%ny) 01150 s%pbbed(:,s%ny+1,:,:)=s%pbbed(:,s%ny,:,:) 01151 s%z0bed(:,s%ny+1)=s%z0bed(:,s%ny) 01152 s%dzbed(:,s%ny+1,:)=s%dzbed(:,s%ny,:) 01153 endif 01154 01155 ! Update representative sed.diameter at the bed for flow friction and output 01156 if (par%ngd>1) then 01157 do j=j1,max(s%ny,1) 01158 do i=2,s%nx 01159 s%D50top = sum(s%pbbed(i,j,1,:)*s%D50) 01160 s%D90top = sum(s%pbbed(i,j,1,:)*s%D90) 01161 enddo 01162 enddo 01163 endif 01164 01165 endif ! if par%t>par%morstart 01166 01167 end subroutine bed_update 01168 01169 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01170 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01171 01172 subroutine update_fractions(par,s,i,j,dz,pb,edg,dzb) 01173 01174 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01175 ! Copyright (C) 2009 Technische Universiteit Delft 01176 ! Bram van Prooijen 01177 ! b.c.vanprooijen@tudelft.nl 01178 ! +31(0)15 2784070 01179 ! Faculty of Civil Engineering and Geosciences 01180 ! department of Hydraulic Engineering 01181 ! PO Box 5048 01182 ! 2600 GA Delft 01183 ! The Netherlands 01184 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01185 01186 use params, only: parameters 01187 use spaceparams 01188 use xmpi_module 01189 01190 01191 implicit none 01192 01193 type(spacepars),target :: s 01194 type(parameters) :: par 01195 01196 integer :: i,j,jg,jd 01197 real*8 :: ED,zbold,dzbt,fac,dzb_loc 01198 real*8, intent(in) :: dzb 01199 real*8 , dimension(par%ngd),intent(in) :: edg 01200 real*8 , dimension(s%nd(i,j)),intent(inout) :: dz 01201 real*8 , dimension(s%nd(i,j),par%ngd),intent(inout) :: pb 01202 01203 real*8 , dimension(:),allocatable,save :: Ap,b 01204 real*8 , dimension(:,:),allocatable,save :: Sm,A 01205 01206 if (.not. allocated(Ap)) then 01207 allocate(Ap (s%nd(1,1))) 01208 allocate(b (s%nd(1,1))) 01209 allocate(Sm (s%nd(1,1),par%ngd)) 01210 allocate(A (s%nd(1,1),3)) 01211 endif 01212 !TODO, dzb_loc is not initialized can be Nan, leading to infinite loop 01213 dzb_loc = dzb 01214 01215 !!!initialize Sm 01216 01217 ED = sum(edg) 01218 ! do t_sub=1,nt_sub !loop over subtimesteps 01219 do while (abs(dzb_loc) .gt. 0.d0) 01220 dzbt = min(dzb_loc,dz(par%nd_var)) ! make sure erosion (dzg is positive) is limited to thickness of variable layer 01221 dzbt = max(dzbt,-par%frac_dz*dz(par%nd_var+1)) ! make sure deposition (dzg is negative) is limited to thickness of first layer below variable layer 01222 01223 fac = dzbt/dzb_loc ! factor over mass change in cells to limit erosion and deposition 01224 01225 dzb_loc = dzb_loc-dzbt ! update dzb 01226 01227 do jg=1,par%ngd 01228 01229 A=0. 01230 Ap=0. 01231 b=0. 01232 01233 Sm(:,jg)=pb(:,jg)*dz*(1.d0-par%por) 01234 01235 !!!build matrix A 01236 select case(par%nd_var) 01237 case(1) 01238 !in this case: A=0 01239 case(2) 01240 A (1,1:3)= (/0.d0 , min(ED,0.d0) , max(ED,0.d0) /) 01241 A (2,1:3)= (/-min(ED,0.d0) , -max(ED,0.d0) , 0.d0 /) 01242 case(3:1000) 01243 A (1,1:3)= (/0.d0 , min(ED,0.d0) , max(ED,0.d0) /) 01244 01245 A (2:par%nd_var-1,1)=-min(ED,0.d0) 01246 A (2:par%nd_var-1,2)=-abs(ED) 01247 A (2:par%nd_var-1,3)=max(ED,0.d0) 01248 01249 A (par%nd_var,1:3)= (/-min(ED,0.d0) , -max(ED,0.d0) , 0.d0 /) 01250 end select 01251 01252 !!!determine RHS 01253 01254 ! Ap makes sure that layer nd_var varies in thickness in time 01255 ! Ap = 0 with single fraction (in case(1)) 01256 Ap(1) = sum(A(1,2:3)*pb(1:2,jg)) 01257 do jd = 2,par%nd_var 01258 Ap(jd) = sum(A (jd,:)*pb(jd-1:jd+1,jg)) 01259 enddo 01260 Ap(par%nd_var+1) = sum(A(par%nd_var+1,1:2)*pb(par%nd_var:par%nd_var+1,jg)) 01261 01262 ! b represents the actual erosion and deposition in the top layer. 01263 ! However, the thickness of the top layer remains constant and instead layer nd_var will breath in thickness 01264 b(1) = -edg(jg) 01265 01266 !!!update Sm 01267 01268 ! Sm is the sediment mass per fraction per layer 01269 ! Sm(1:par%nd_var+1,jg) = Sm(1:par%nd_var+1,jg) + par%dt/nt_sub*(Ap(1:par%nd_var+1)+b(1:par%nd_var+1)) 01270 Sm(1:par%nd_var+1,jg) = Sm(1:par%nd_var+1,jg) + par%dt*fac*(Ap(1:par%nd_var+1)+b(1:par%nd_var+1)) 01271 01272 enddo !fractions 01273 01274 ! From Sm we can compute the new fraction ratios per layer and the layer thickness... 01275 do jd=1,par%nd_var+1 01276 if (sum(Sm(jd,:))>0) then 01277 pb(jd,:) = Sm(jd,:)/sum(Sm(jd,:)) 01278 else 01279 pb(jd,:) = pb(jd,:) 01280 endif 01281 dz(jd) = sum(Sm(jd,:))/(1.d0-par%por) 01282 enddo 01283 01284 !!! modify grid 01285 01286 !merge two upper layers in case of erosion 01287 if (dz(par%nd_var) .lt. par%merge*dz(par%nd_var+1)) then 01288 forall (jg=1:par%ngd) 01289 pb(par%nd_var,jg) = (dz(par%nd_var)*pb(par%nd_var,jg) + dz(par%nd_var+1)* & 01290 pb(par%nd_var+1,jg))/(dz(par%nd_var)+dz(par%nd_var+1)) 01291 pb(par%nd_var+1:s%nd(i,j)-1,jg) = pb(par%nd_var+2:s%nd(i,j),jg) 01292 pb(s%nd(i,j),jg) = pb(s%nd(i,j),jg) 01293 endforall 01294 s%z0bed(i,j) = s%z0bed(i,j)-dz(par%nd_var+1) 01295 dz(par%nd_var) = dz(par%nd_var+1)+dz(par%nd_var) 01296 endif 01297 !split upper layer in case of sedimentation 01298 if (dz(par%nd_var)>par%split*dz(par%nd_var+1)) then 01299 pb(par%nd_var+1:s%nd(i,j),:) = pb(par%nd_var:s%nd(i,j)-1,:) 01300 s%z0bed(i,j) = s%z0bed(i,j)+dz(par%nd_var+1) 01301 dz(par%nd_var) = dz(par%nd_var)-dz(par%nd_var+1) 01302 endif 01303 enddo ! nt_sub 01304 01305 pb = max(0.d0,min(pb,1.d0)) 01306 01307 zbold = s%zb(i,j) 01308 s%zb(i,j) = s%z0bed(i,j)+sum(dz) 01309 s%dzbnow(i,j) = s%dzbnow(i,j)+(s%zb(i,j)-zbold) 01310 s%sedero(i,j) = s%sedero(i,j)+(s%zb(i,j)-zbold) 01311 s%structdepth(i,j) = max(0.d0,s%structdepth(i,j)+(s%zb(i,j)-zbold)) 01312 01313 end subroutine update_fractions 01314 01315 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01316 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01317 01318 subroutine sedtransform(s,par) 01319 use params, only: parameters 01320 use spaceparams 01321 use readkey_module 01322 use xmpi_module 01323 use paramsconst 01324 01325 implicit none 01326 01327 type(spacepars),target :: s 01328 type(parameters) :: par 01329 01330 integer :: i,j,jg, ii 01331 real*8 :: z0,dcf,dcfin,ML 01332 real*8 :: Te,Sster,cc1,cc2,wster,Ass 01333 real*8 :: kl,alpha,alpha1,alpha2,beta,psi 01334 real*8 , save :: delta,kvis,onethird,twothird,phi 01335 real*8 , dimension(:),allocatable ,save :: dster,ws0, shieldscrit, sigz, ceqssteps, hhsteps 01336 real*8 , dimension(:,:),allocatable ,save :: vmg,Cd,Asb,dhdx,dhdy,Ts,hfac 01337 real*8 , dimension(:,:),allocatable ,save :: urms2,Ucr,Ucrc,Ucrw,term1,B2,srfTotal,srfRhee,vero,Ucrb,Ucrs 01338 real*8 , dimension(:,:),allocatable ,save :: uandv,b,fslope,hloc,ceqs,ceqb,fallvelredfac 01339 real*8 , dimension(:,:,:),allocatable,save :: w 01340 real*8 , dimension(:,:),allocatable ,save :: uorb, A, ksw, fw, uw, tauwav, muw, fc, f1c, tauc, muc, taubcw, taucr, used, ue 01341 real*8 :: ca, refA, E, Me, M, Eswm, Eswb, Esw, Esc, uster, deltar, delw, ta, Escm, ceqexplicit, ceqimplicit, hhtmp, hhtmp2, dhhtmp, sigs, ceq_tmp 01342 01343 !include 's.ind' 01344 !include 's.inp' 01345 01346 if (.not. allocated(vmg)) then 01347 allocate (vmg (s%nx+1,s%ny+1)) 01348 allocate (term1 (s%nx+1,s%ny+1)) 01349 allocate (B2 (s%nx+1,s%ny+1)) 01350 allocate (Cd (s%nx+1,s%ny+1)) 01351 allocate (Asb (s%nx+1,s%ny+1)) 01352 allocate (Ucr (s%nx+1,s%ny+1)) 01353 allocate (Ucrc (s%nx+1,s%ny+1)) 01354 allocate (Ucrw (s%nx+1,s%ny+1)) 01355 allocate (urms2 (s%nx+1,s%ny+1)) 01356 allocate (hloc (s%nx+1,s%ny+1)) 01357 allocate (Ts (s%nx+1,s%ny+1)) 01358 allocate (ceqs (s%nx+1,s%ny+1)) 01359 allocate (ceqb (s%nx+1,s%ny+1)) 01360 allocate (srfTotal(s%nx+1,s%ny+1)) ! Lodewijk 01361 allocate (Ucrb (s%nx+1,s%ny+1)) ! Lodewijk 01362 allocate (Ucrs (s%nx+1,s%ny+1)) ! Lodewijk 01363 allocate (srfRhee(s%nx+1,s%ny+1)) ! Lodewijk 01364 allocate (vero (s%nx+1,s%ny+1)) ! Lodewijk 01365 allocate (fallvelredfac(s%nx+1,s%ny+1)) ! Lodewijk 01366 allocate (w (s%nx+1,s%ny+1,par%ngd)) ! Lodewijk 01367 allocate (dster (par%ngd)) 01368 allocate (ws0 (par%ngd)) 01369 allocate (shieldscrit(par%ngd)) 01370 allocate (dhdx (s%nx+1,s%ny+1)) 01371 allocate (dhdy (s%nx+1,s%ny+1)) 01372 allocate (uandv (s%nx+1,s%ny+1)) 01373 allocate (b (s%nx+1,s%ny+1)) 01374 allocate (fslope(s%nx+1,s%ny+1)) 01375 allocate (hfac (s%nx+1,s%ny+1)) 01376 ! Van Rijn (1993) by Kees 01377 allocate (used (s%nx+1,s%ny+1)) 01378 allocate (ue (s%nx+1,s%ny+1)) 01379 allocate (uorb (s%nx+1,s%ny+1)) 01380 allocate (A (s%nx+1,s%ny+1)) 01381 allocate (ksw (s%nx+1,s%ny+1)) 01382 allocate (fw (s%nx+1,s%ny+1)) 01383 allocate (uw(s%nx+1,s%ny+1)) 01384 allocate (tauwav (s%nx+1,s%ny+1)) 01385 allocate (muw (s%nx+1,s%ny+1)) 01386 allocate (fc (s%nx+1,s%ny+1)) 01387 allocate (f1c (s%nx+1,s%ny+1)) 01388 allocate (muc (s%nx+1,s%ny+1)) 01389 allocate (tauc (s%nx+1,s%ny+1)) 01390 allocate (taubcw(s%nx+1,s%ny+1)) 01391 allocate (taucr (s%nx+1,s%ny+1)) 01392 allocate(sigz(par%kmax)) 01393 allocate(hhsteps(par%kmax+1)) 01394 allocate(ceqssteps(par%kmax+1)) 01395 01396 vmg = 0.d0 01397 onethird=1.d0/3.d0 01398 twothird=2.d0/3.d0 01399 phi = par%reposeangle/180*par%px ! Angle of internal friction 01400 ! Robert: do only once, not necessary every time step 01401 do jg=1,par%ngd 01402 ! cjaap: compute fall velocity with simple expression from Ahrens (2000) 01403 Te = 20.d0 01404 kvis = 4.d0/(20.d0+Te)*1d-5 ! Van rijn, 1993 01405 Sster = s%D50(jg)/(4*kvis)*sqrt((par%rhos/par%rho-1)*par%g*s%D50(jg)) 01406 cc1 = 1.06d0*tanh(0.064d0*Sster*exp(-7.5d0/Sster**2)) 01407 cc2 = 0.22d0*tanh(2.34d0*Sster**(-1.18d0)*exp(-0.0064d0*Sster**2)) 01408 wster = cc1+cc2*Sster 01409 ws0(jg) = wster*sqrt((par%rhos/par%rho-1.d0)*par%g*s%D50(jg)) 01410 ! RJ: for modeling gravel 01411 delta = (par%rhos-par%rho)/par%rho 01412 dster(jg)=(delta*par%g/1.d-12)**onethird*s%D50(jg) 01413 shieldscrit(jg) = 0.3d0/(1+1.2d0*dster(jg))+0.055d0*(1-exp(-0.02d0*dster(jg))) ! Soulsby, 1997 (eq 76) 01414 if (par%fallvelred==0) then 01415 w(:,:,jg) = ws0(jg) 01416 endif 01417 enddo 01418 endif 01419 01420 01421 ! Lodewijk: calculate fall velocity reduction coefficient based on concentration of previous time step 01422 ! Rowe (1987) made an estimation of the exponent alpha by fitting a logarithmic function on a dataset of Richardson and Zaki (1954). 01423 if (par%fallvelred==1) then 01424 do jg=1,par%ngd 01425 alpha = 2.35d0*(2.d0+0.175d0*(ws0(jg)*s%D50(jg)/kvis)**0.75d0)/(1.d0+0.175d0*(ws0(jg)*s%D50(jg)/kvis)**0.75d0) 01426 fallvelredfac = (1.d0-s%ccg(:,:,jg))**(alpha) 01427 w(:,:,jg) = ws0(jg)*fallvelredfac 01428 enddo 01429 endif 01430 ! 01431 ! hloc = max(hh,0.01d0) ! Jaap 01432 hloc = max(s%hh,0.01) 01433 ! Compute mean fall velocity 01434 par%ws=0.d0 01435 do jg=1,par%ngd 01436 par%ws=par%ws+w(1,1,jg) 01437 enddo 01438 par%ws=par%ws/par%ngd 01439 01440 ! 01441 ! compute near bed turbulence 01442 ! 01443 ! due to short waves 01444 01445 if (par%swave==1) then 01446 ! wave breaking induced turbulence due to short waves 01447 do j=1,s%ny+1 01448 do i=1,s%nx+1 01449 ! compute mixing length 01450 ! ML = 2*R(i,j)*par%Trep/(par%rho*c(i,j)*max(H(i,j),par%eps)) 01451 ML = dsqrt(2*s%R(i,j)*par%Trep/(par%rho*max(s%c(i,j),1d-10))) 01452 ! ML = 0.9d0*H(i,j) 01453 ML = min(ML,hloc(i,j)); 01454 ! exponential decay turbulence over depth 01455 dcfin = exp(min(100.d0,hloc(i,j)/max(ML,0.00000000000000001d0))) 01456 dcf = min(1.d0,1.d0/(dcfin-1.d0)) 01457 ! Jaap: new approach: compute kb based on waveturb result 01458 s%kb(i,j) = s%kturb(i,j)*dcf 01459 ! 01460 if (par%turb == TURB_BORE_AVERAGED) then 01461 s%kb(i,j) = s%kb(i,j)*par%Trep/s%Tbore(i,j) 01462 endif 01463 01464 enddo 01465 ! Jaap: rundown jet creating additional turbulence 01466 if (par%swrunup==1)then 01467 s%kb(nint(s%istruct(j)),j) = s%kb(nint(s%istruct(j)),j) + par%jetfac* & 01468 (s%E(nint(s%istruct(j)),j)*s%strucslope(j)*sqrt(par%g/s%hh(nint(s%istruct(j)),j)))**twothird 01469 endif 01470 enddo 01471 elseif (par%wavemodel==WAVEMODEL_NONH) then 01472 do j=1,s%ny+1 01473 do i=1,s%nx+1 01474 !ML=max(s%rolthick(i,j),0.07d0*max(s%hh(i,j),par%hmin)) 01475 !s%kb(i,j) = s%kturb(i,j)*ML/max(s%hh(i,j),par%hmin) ! Simpler expression 01476 s%kb(i,j) = s%kturb(i,j) ! even simpler expression :-) 01477 enddo 01478 enddo 01479 endif !par%swave == 1 01480 01481 ! switch to include long wave stirring 01482 if (par%lws==1) then 01483 vmg = dsqrt(s%ue**2+s%ve**2) 01484 elseif (par%lws==0) then 01485 ! vmg lags on actual mean flow; but long wave contribution to mean flow is included... 01486 vmg = (1.d0-1.d0/par%cats/par%Trep*par%dt)*vmg + (1.d0/par%cats/par%Trep*par%dt)*dsqrt(s%ue**2+s%ve**2) 01487 endif 01488 01489 urms2 = s%urms**2.d0+1.45d0*s%kb 01490 01491 do jg = 1,par%ngd 01492 01493 Ts = par%tsfac*hloc/w(:,:,jg) 01494 if (par%oldTsmin==1) then 01495 s%Tsg(:,:,jg) = max(Ts,par%Tsmin) 01496 else 01497 s%Tsg(:,:,jg) = max(Ts,par%dtlimTs*par%dt) 01498 endif 01499 ! 01500 ! calculate treshold velocity Ucr 01501 ! 01502 if (par%form==FORM_SOULSBY_VANRIJN) then ! Soulsby van Rijn 01503 if(s%D50(jg)<=0.0005d0) then 01504 Ucr=0.19d0*s%D50(jg)**0.1d0*log10(4.d0*hloc/s%D90(jg)) 01505 else !Dano see what happens with coarse material 01506 Ucr=8.5d0*s%D50(jg)**0.6d0*log10(4.d0*hloc/s%D90(jg)) 01507 end if 01508 elseif ((par%form==FORM_VANTHIEL_VANRIJN) .or. (par%form==FORM_VANRIJN1993)) then 01509 ! needed for full Van Thiel de Vries & Reniers 2008 or bed load Van Rijn 1993 01510 if(s%D50(jg)<=0.0005) then 01511 Ucrc=0.19d0*s%D50(jg)**0.1d0*log10(4.d0*hloc/s%D90(jg)) !Shields 01512 Ucrw=0.24d0*(delta*par%g)**0.66d0*s%D50(jg)**0.33d0*par%Trep**0.33d0 !Komar and Miller (1975) 01513 else if(s%D50(jg)<=0.002) then 01514 Ucrc=8.5d0*s%D50(jg)**0.6d0*log10(4.d0*hloc/s%D90(jg)) !Shields 01515 Ucrw=0.95d0*(delta*par%g)**0.57d0*s%D50(jg)**0.43*par%Trep**0.14 !Komar and Miller (1975) 01516 else if(s%D50(jg)>0.002) then 01517 Ucrc=1.3d0*sqrt(delta*par%g*s%D50(jg))*(hloc/s%D50(jg))**(0.5d0*onethird) !Maynord (1978) --> also Neill (1968) where 1.3d0 = 1.4d0 01518 Ucrw=0.95d0*(delta*par%g)**0.57d0*s%D50(jg)**0.43*par%Trep**0.14 !Komar and Miller (1975) 01519 end if 01520 B2 = vmg/max(vmg+dsqrt(urms2),par%eps) 01521 Ucr = B2*Ucrc + (1-B2)*Ucrw !Van Rijn 2007 (Bed load transport paper) 01522 end if 01523 01524 ! Lodewijk: implementation Rhee (2010), reduction sediment transport due dilatancy 01525 srfRhee(:,:) = 0.d0 01526 srfTotal(:,:) = 1.d0 01527 if (par%dilatancy == 1) then 01528 vero(:,:) = max(0.d0,-1.d0*s%dzbdt) ! Erosion velocity, for now asume it equal to -s%dzbdt of the previous time step 01529 kl = par%g/(160.d0*kvis)*(s%D15(jg)**2.d0)*((par%por**3.d0)/(1.d0-par%por)**2.d0) ! Permeability, Adel 1987, which is based on the Ergun equation 01530 ! bed porosity, estimated here as maximum porosity, to be added to user input 01531 ! A=3/4 for single particles and A=1/(1-n0) for a continuum 01532 ! Reduction factor on the critical Shields parameter by dilatancy (Van Rhee, 2010) 01533 srfRhee(:,:) = vero(:,:)/kl*(par%pormax-par%por)/(1.d0-par%pormax)*par%rheeA/delta 01534 endif 01535 ! Lodewijk: implementation bed slope reduction on critical flow velocity 01536 if (par%bdslpeffini == BDSLPEFFINI_NONE) then 01537 srfTotal(:,:) = 1.d0 + srfRhee(:,:) 01538 elseif (par%bdslpeffini == BDSLPEFFINI_TOTAL .or. par%bdslpeffini == BDSLPEFFINI_BED) then 01539 do j=1,s%ny+1 01540 do i=1,s%nx+1 01541 ! Prevent NaN values if too small values 01542 if ((dabs(s%ue(i,j)) > 0.000001d0 .or. dabs(s%ve(i,j)) > 0.000001d0) .and. & 01543 (dabs(s%dzbdx(i,j))>0.000001d0 .or. dabs(s%dzbdy(i,j))>0.000001d0)) then 01544 ! Angle between the x-axis and the flow velocity 01545 ! REMARK: also include waves in the velocity? 01546 if (s%ue(i,j) < 0.d0) then 01547 alpha1 = datan(s%ve(i,j)/s%ue(i,j)) + par%px 01548 else 01549 alpha1 = datan(s%ve(i,j)/s%ue(i,j)) 01550 endif 01551 ! Angle between the x-axis and the bed slope vector directed in down-slope direction, derived in thesis Lodewijk 01552 if (s%dzbdy(i,j) >= 0.d0) then 01553 alpha2 = -datan(s%dzbdx(i,j)/s%dzbdy(i,j))+1.5d0*par%px 01554 else 01555 alpha2 = -datan(s%dzbdx(i,j)/s%dzbdy(i,j))+0.5d0*par%px 01556 endif 01557 psi = alpha1-(alpha2-par%px) ! Angle between the flow direction and the up-slope directed vector 01558 if (dabs(s%dzbdx(i,j))<0.000001d0) then ! A smaller slope could result in a NaN for beta 01559 ! Beta purely based on dzbdy 01560 beta = datan(dabs(s%dzbdy(i,j))) 01561 else 01562 beta = datan(dabs(s%dzbdx(i,j)/dsin(datan(s%dzbdx(i,j)/s%dzbdy(i,j))))) ! Maximum absolute bed slope angle, derived in thesis Lodewijk 01563 endif 01564 beta = min(beta,phi) ! Take min to exclude NaN's 01565 if (par%dilatancy == 1) then 01566 srfTotal(i,j) = (dcos(psi)*dsin(beta)+dsqrt( & 01567 ((srfRhee(i,j))**2+2*srfRhee(i,j)*dcos(beta)+dcos(beta)**2 & 01568 )*dtan(phi)**2-dsin(psi)**2*dsin(beta)**2 & 01569 ))/dtan(phi) ! Soulsby (1997), modified by Lodewijk (see Thesis) 01570 else 01571 srfTotal(i,j) = (dcos(psi)*dsin(beta)+ & 01572 dsqrt(dcos(beta)**2*dtan(phi)**2-dsin(psi)**2*dsin(beta)**2))/dtan(phi) ! Soulsby (1997) 01573 endif 01574 endif 01575 end do 01576 end do 01577 endif 01578 ! Calculate the new critical velocity based on the modification factors on the Shields parameter, bed slope only on bed load 01579 Ucrb(:,:) = Ucr(:,:)*sqrt(srfTotal) ! Lodewijk 01580 if (par%bdslpeffini == BDSLPEFFINI_TOTAL) then 01581 Ucrs = Ucrb 01582 else 01583 Ucrs = Ucr*(1.d0+sqrt(srfRhee)) ! Lodewijk, no effect on suspended load by bed slope 01584 endif 01585 01586 01587 if (par%form==FORM_SOULSBY_VANRIJN) then ! Soulsby van Rijn 01588 ! 01589 ! drag coefficient 01590 z0 = par%z0 01591 Cd=(0.40d0/(log(max(hloc,10.d0*z0)/z0)-1.0d0))**2 01592 ! 01593 ! transport parameters 01594 Asb=0.005d0*hloc*(s%D50(jg)/hloc/(delta*par%g*s%D50(jg)))**1.2d0 ! bed load coefficent 01595 Ass=0.012d0*s%D50(jg)*dster(jg)**(-0.6d0)/(delta*par%g*s%D50(jg))**1.2d0 ! suspended load coeffient 01596 ! 01597 term1=(vmg**2+0.018/Cd*par%sws*urms2) ! Make 0.018/Cd is always smaller than the flow friction coefficient 01598 ! 01599 ! reduce sediment suspensions for (inundation) overwash conditions with critical flow velocitties 01600 ! vmag2=min(vmag2,par%smax*par%C**2*D50(jg)*delta) 01601 ! vmag2=min(vmag2,par%smax*par%g/par%cf*D50(jg)*delta) ! In terms of cf 01602 ! term1=sqrt(vmag2+0.018d0/Cd*urms2) ! nearbed-velocity 01603 ! the two above lines are comment out and replaced by a limit on total velocity u2+urms2, robert 1/9 and ap 28/11 01604 ! 01605 term1=min(term1,par%smax*par%g/s%cf*s%D50(jg)*delta) 01606 term1=sqrt(term1) 01607 ! 01608 ceqb = 0.d0 !initialize ceqb 01609 ceqs = 0.d0 !initialize ceqs 01610 do j=1,s%ny+1 01611 do i=1,s%nx 01612 ! Lodewijk: separate bed load from suspended load since Ucr not anymore the same 01613 if(term1(i,j)>Ucrb(i,j) .and. hloc(i,j)>par%eps) then 01614 ceqb(i,j)=Asb(i,j)*(term1(i,j)-Ucrb(i,j))**2.4d0 01615 end if 01616 if(term1(i,j)>Ucrs(i,j) .and. hloc(i,j)>par%eps) then 01617 ceqs(i,j)=Ass*(term1(i,j)-Ucrs(i,j))**2.4d0 01618 end if 01619 end do 01620 end do 01621 ! 01622 elseif (par%form==FORM_VANTHIEL_VANRIJN) then ! Van Thiel de Vries & Reniers 2008 01623 ! 01624 ! transport parameters 01625 Asb=0.015d0*hloc*(s%D50(jg)/hloc)**1.2d0/(delta*par%g*s%D50(jg))**0.75d0 !bed load coefficent 01626 Ass=0.012d0*s%D50(jg)*dster(jg)**(-0.6d0)/(delta*par%g*s%D50(jg))**1.2d0 !suspended load coeffient 01627 ! 01628 ! Jaap: par%sws to set short wave stirring to zero 01629 ! Jaap: Van Rijn use Peak orbital flow velocity --> 0.64 corresponds to 0.4 coefficient regular waves Van Rijn (2007) 01630 term1=vmg**2+0.64d0*par%sws*urms2 01631 ! reduce sediment suspensions for (inundation) overwash conditions with critical flow velocitties 01632 term1=min(term1,par%smax*par%g/max(s%cf,1d-10)*s%D50(jg)*delta) 01633 term1=sqrt(term1) 01634 ! 01635 ceqb = 0.d0 !initialize ceqb 01636 ceqs = 0.d0 !initialize ceqs 01637 do j=1,s%ny+1 01638 do i=1,s%nx 01639 ! Lodewijk: sepperate bed load from suspended load since Ucr not anymore the same 01640 if(term1(i,j)>Ucrb(i,j) .and. hloc(i,j)>par%eps) then 01641 ceqb(i,j)=Asb(i,j)*(term1(i,j)-Ucrb(i,j))**1.5 01642 end if 01643 if(term1(i,j)>Ucrs(i,j) .and. hloc(i,j)>par%eps) then 01644 ceqs(i,j)=Ass*(term1(i,j)-Ucrs(i,j))**2.4 01645 end if 01646 end do 01647 end do 01648 ! 01649 elseif (par%form==FORM_VANRIJN1993) then ! Van Rijn (1993) a la Delft3D 01650 ! 01651 ! General parameters 01652 ue = dsqrt(vmg**2) ! NOT similar to Van Thiel -> velocity magnitude for stirring sediment 01653 used = vmg + s%ua ! velocity used for sediment transport (reduced with asymmetry) 01654 ! 01655 ! Bed load transport (Delft3D-FLOW manual; eq 11.82) 01656 ! 01657 do j=1,s%ny+1 01658 do i=1,s%nx+1 01659 if (ue(i,j)>Ucrb(i,j) .and. hloc(i,j)>par%eps) then ! Ucrs is weighted current (including waves) 01660 Me = (used(i,j)-Ucrb(i,j))**2 / ((delta*par%g*s%D50(jg))) ! Effective mobility parameter 01661 M = (used(i,j)-0)**2 / ((delta*par%g*s%D50(jg))) ! "normal" mobility parameter 01662 Asb(i,j) = 0.006d0 * s%D50(jg) * ws0(jg) ! bed load coefficent (without ps) 01663 ceqb(i,j) = Asb(i,j) * (M**0.5)* (Me**0.7) ! calculate the main part 01664 ceqb(i,j) = ceqb(i,j) / used(i,j) ! goal is sediment concentration: divide by velocity 01665 else 01666 ceqb(i,j) = 0 01667 end if 01668 end do 01669 end do 01670 ! 01671 ! Suspended transport (Van Rijn, 1993: Delft3D-FLOW manual) 01672 ! 01673 deltar = par%deltar ! ripple height input (eq. 11.78) 01674 ksw = par%rwave*deltar ! wave-related roughness -> based on ripple height (eq. 11.78) 01675 ksw = max(min(0.1, ksw), 0.01) ! numerical limits: not larger or smaller 01676 ! orbital velocityand peak orbital excursion 01677 uorb = par%px*s%H/par%Trep/sinh(min(max(s%k,0.01d0)*max(s%hh,par%delta*s%H),10.0d0)) ! orbital velocity (linear wave theory) 01678 A = uorb*par%Trep / (2.0*par%px) ! peak orbital excursion (below eq. 11.80) 01679 ! numerical limits for A, otherwise infinity problems 01680 where (A<0.1d0) 01681 A = 0.1d0 01682 endwhere 01683 ! 01684 ! Calculate bed-shear stress due to waves 01685 fw = min(exp( - 6.0 + 5.2*(A/ksw)**( - 0.19)), 0.3) ! Van Rijn & Kroon (1992); eq 13 below 01686 muw = 0.6/dster(jg) ! efficiency waves 01687 tauwav = 0.25 * par%rho * fw * uorb**2 ! bed shear stress due to waves (eq. 11.76) 01688 ! 01689 ! Calculate bed-shear stress due to currents 01690 f1c = 0.24*log10(12.0*s%hh/(3.0*3*s%D90(jg)))**( - 2) ! total-current relation factor (eq. 11.73) 01691 fc = 0.24*log10(12.0*s%hh/deltar)**( - 2) ! grain-related factor (eq. 11.72) 01692 muc = f1c/fc ! efficiency current 01693 tauc = 0.125d0* par%rho * fc * (s%ue**2+s%ve**2) ! Van Rijn & Kroon (1992); eq. 13 01694 ! 01695 ! Calculate bed shear stress ratio: combined waves and currents 01696 taubcw = muc*tauc + muw*tauwav ! combined shear stress (eq. 11.70) 01697 taucr = shieldscrit(jg) * par%g * (par%rhos-par%rho) * s%D50(jg) ! critical bed shear stress (Soulsby, 1997 at Eq. 74; page 104) 01698 ! 01699 ! Loop over every grid cell where critical bed shear stress < combined shear stress due to waves and currents 01700 ! clean variables 01701 s%ccz(:,:,:) = 0 01702 s%refA(:,:) = 0 01703 s%ca(:,:) = 0 01704 do j=1,s%ny+1 01705 do i=1,s%nx+1 01706 if (taubcw(i,j)>taucr(i,j) .and. hloc(i,j)>par%eps) then 01707 ! 01708 ! A) Reference level 01709 refA = 0.5*deltar ! reference level is half the ripple height 01710 refA = max(0.01, refA) ! minimum reference level 01711 refA = min(0.2*s%hh(i,j), refA) ! maximum reference level 20% of the water depth -> same Delft3D 01712 ! 01713 ! B) Compute wave boundary laver thickness 01714 delw = 0.072*A(i,j)*(A(i,j)/ksw(i,j))**(-0.25) 01715 ! 01716 ! C) Calculate Van Rijn's dimensionless bed-shear stress for reference concentration at z=a 01717 ta = max(0.0, (muc(i,j)*tauc(i,j) + muw(i,j)*tauwav(i,j))/taucr(i,j) - 1.0) 01718 ! 01719 ! D) Calculate Van Rijn's reference concentration 01720 ca = 0.015*s%d50(jg)*ta**1.5/(refA*dster(jg)**0.3) ! Van Rijn, 1984; no rho in there) 01721 ca = min(ca, 0.05) ! maximum ca value 01722 ! 01723 ! E) Depth-averaged mixing due to waves 01724 ! 1) Van Rijn & Kroon (1992); eq. 9 (maximum) 01725 Eswm = 0.035 * s%H(i,j)*s%hh(i,j) / par%Trep 01726 ! 2) Van Rijn & Kroon (1992); eq. 8 (at the bed) with 3 deltar = thicknes layer 01727 Eswb = 0.004*dster(jg)*uorb(i,j)*(3.0*delw) 01728 ! 01729 ! F) Depth-averaged mixing due to currents 01730 uster = ((s%taubx(i,j)**2 + s%tauby(i,j)**2)**0.5 / par%rho)**0.5 ! calculate bed shear velocity 01731 Escm = 0.25 * par%vonkar * uster * s%hh(i,j) ! Van Rijn & Kroon (1992); eq. 10 (maximum) 01732 ! 01733 ! G) Numerically integrate the concentration profile (no analyical expression with varying mixing exists!) 01734 ! one could assume a constant mixing coefficient: in that case exponential profile with analyical epxression 01735 ! 1) Create the grid on which we approximate the concentration profile 01736 ! Grid goes from reference level to water depth 01737 hhsteps(1) = refA 01738 do ii=1,(par%kmax) 01739 sigs = 0.01 ! starting percentile; 1% now 01740 sigz(ii) = sigs*(1/sigs)**(float(ii-1)/float(par%kmax-1)) ! could place outside the loop for efficiency 01741 hhsteps(ii+1) = refA + (s%hh(i,j)-refA) * sigz(ii) 01742 enddo 01743 ! 01744 ! 2) Now numerical integrate 01745 ! Start concentration is the reference concentration of Van Rijn, 1984 01746 ceqssteps(1) = ca 01747 do ii = 1, (par%kmax) 01748 ! 01749 ! i) Determine water depth 01750 hhtmp = hhsteps(ii) ! current water depth 01751 hhtmp2 = hhsteps(ii+1) ! water depth in next step 01752 dhhtmp = hhtmp2-hhtmp ! change in water depth in this step -> related to sigma layer 01753 ! 01754 ! ii) Determine e,waves 01755 if (hhtmp < (3*delw)) then 01756 Esw = Eswb 01757 elseif (hhtmp > (0.5*s%hh(i,j))) then 01758 Esw = Eswm 01759 else 01760 Esw = Eswb + (Eswm-Eswb)* (hhtmp - (3*delw)) / (0.5*s%hh(i,j) - 3*delw) 01761 endif 01762 ! 01763 ! iii) Determine e,currents 01764 if (hhtmp > (0.5*s%hh(i,j))) then 01765 Esc = Escm ! Van Rijn & Kroon (1992); eq. 10 (maximum) 01766 else 01767 Esc = par%vonkar * 1* uster * hhtmp * (1- hhtmp/s%hh(i,j)) ! Van Rijn & Kroon (1992); eq. 10 (at certain depth) 01768 endif 01769 ! 01770 ! iv) Combined mixing coefficient due to currents and waves 01771 E = (Esw**2 + Esc**2)**0.5 ! Van Rijn & Kroon (1992); eq. 5 01772 ! 01773 if (E > 0) then 01774 ! v) Calculcate new concentration 01775 ! a) Explicit first step 01776 ceqexplicit = ceqssteps(ii) - ws0(jg) * ceqssteps(ii)/E * dhhtmp 01777 if (ceqexplicit< 0) then 01778 ceqexplicit = 0 ! numerical limit; overcome overshooting of numerical approximation 01779 endif 01780 ! b) Implicit second step 01781 ceqimplicit = ceqssteps(ii) * (E / (dhhtmp * (ws0(jg)+E/dhhtmp))) ! no limit needed 01782 ! c) Combined method with theta = 0.5 -> second order 01783 ceqssteps(ii+1) = 0.5*ceqexplicit + 0.5*ceqimplicit 01784 if (ceqssteps(ii+1) < 0) then 01785 ceqssteps(ii+1) = 0 ! numerical limit; overcome overshooting of numerical approximation 01786 endif 01787 else 01788 ! No mixing; so no equilibrium in the vertical 01789 ceqssteps = 0 01790 endif 01791 enddo 01792 ! 01793 ! E) Save concentration profile, reference concentraton and reference level 01794 s%refA(i,j) = refA ! reference level 01795 s%ca(i,j) = ca ! reference concentration 01796 do ii = 1, (par%kmax) 01797 s%ccz(i,j,ii) = ceqssteps(ii)*0.5 + ceqssteps(ii+1)*0.5 01798 enddo 01799 ! 01800 ! F) Now determine the depth-averaged concentration (sum divided by total length) 01801 if (s%hh(i,j) < refA) then 01802 ! assume that the depth-averaged concentration is similar to reference concentration 01803 ! not needed anymore; 20% water depth constrain 01804 ceqs(i,j) = ca 01805 do ii = 1, (par%kmax) 01806 s%ccz(i,j,ii) = ca 01807 enddo 01808 else 01809 ! average of the 'active part of the water colum' + reduction factor based on reference layer thickness 01810 ceq_tmp = 0 01811 ceq_tmp = sigz(1) * (ceqssteps(2)*0.5 + ceqssteps(1)*0.5) 01812 do ii = 2, (par%kmax) 01813 ceq_tmp = ceq_tmp + (sigz(ii)-sigz(ii-1)) * (ceqssteps(ii+1)*0.5 + ceqssteps(ii)*0.5) 01814 enddo 01815 ceqs(i,j) =ceq_tmp 01816 endif 01817 else 01818 ceqs(i,j) = 0 01819 endif 01820 enddo 01821 enddo 01822 end if 01823 ! 01824 ceqb = min(ceqb/hloc,par%cmax/2) ! maximum equilibrium bed concentration 01825 s%ceqbg(:,:,jg) = (1-par%bulk)*ceqb*s%sedcal(jg)*s%wetz 01826 ceqs = min(ceqs/hloc,par%cmax/2) ! maximum equilibrium suspended concentration 01827 s%ceqsg(:,:,jg) = (ceqs+par%bulk*ceqb)*s%sedcal(jg)*s%wetz 01828 ! Jaap: old brute method to prevent strong coastline erosion 01829 ! where (hloc<=par%hmin) ceqsg(:,:,jg) = 0.d0 01830 enddo ! end of grain size classes 01831 ! end of grain size classes 01832 01833 end subroutine sedtransform 01834 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01835 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 01836 01837 subroutine Nielsen2006(s,par) 01838 01839 use params, only: parameters 01840 use spaceparams 01841 use xmpi_module 01842 use math_tools 01843 use paramsconst 01844 01845 IMPLICIT NONE 01846 01847 type(spacepars),target :: s 01848 type(parameters) :: par 01849 01850 real*8 :: Tsmooth,factime,omegap,dstar 01851 real*8,save :: phirad,delta,khlim,reposerad,reposedzdx 01852 01853 integer :: i,jg 01854 01855 real*8,dimension(:,:),allocatable,save :: dudtsmooth 01856 real*8,dimension(:,:),allocatable,save :: fsed 01857 real*8,dimension(:,:),allocatable,save :: Arms,umeanupd,uvarupd 01858 real*8,dimension(:,:),allocatable,save :: umeanupdphi,uvarupdphi 01859 real*8,dimension(:,:),allocatable,save :: shields,qsedu 01860 real*8,dimension(:,:),allocatable,save :: blphi,facbl,facrw,facslp 01861 real*8,dimension(:,:),allocatable,save :: ulocal,ulocalold,philocal 01862 real*8,dimension(:,:),allocatable,save :: dcfinl,dcfl,fe,cffac,ustar 01863 real*8,dimension(:) ,allocatable,save :: shieldscrit 01864 01865 if (.not. allocated(dudtsmooth)) then 01866 allocate(dudtsmooth(s%nx+1,s%ny+1)) 01867 allocate(fsed(s%nx+1,s%ny+1)) 01868 allocate(shields(s%nx+1,s%ny+1)) 01869 allocate(qsedu(s%nx+1,s%ny+1)) 01870 allocate (blphi (s%nx+1,s%ny+1)) 01871 allocate (facbl (s%nx+1,s%ny+1)) 01872 allocate (facrw (s%nx+1,s%ny+1)) 01873 allocate (facslp (s%nx+1,s%ny+1)) 01874 allocate (ulocal (s%nx+1,s%ny+1)) 01875 allocate (ulocalold (s%nx+1,s%ny+1)) 01876 allocate(philocal(s%nx+1,s%ny+1)) 01877 allocate(umeanupdphi(s%nx+1,s%ny+1)) 01878 allocate(uvarupdphi(s%nx+1,s%ny+1)) 01879 allocate(dcfinl(s%nx+1,s%ny+1)) 01880 allocate(dcfl(s%nx+1,s%ny+1)) 01881 allocate(cffac(s%nx+1,s%ny+1)) 01882 cffac = 0.d0 01883 allocate(Arms(s%nx+1,s%ny+1)) 01884 allocate(umeanupd(s%nx+1,s%ny+1)) 01885 allocate(uvarupd(s%nx+1,s%ny+1)) 01886 allocate(ustar(s%nx+1,s%ny+1)) 01887 allocate(shieldscrit(par%ngd)) 01888 umeanupd = 0.d0 01889 uvarupd = 0.d0 01890 01891 if(par%streaming==1) then 01892 allocate(fe(s%nx+1,s%ny+1)) 01893 endif 01894 fe = 0.d0 01895 fsed = 0.d0 01896 phirad = par%phit/180*par%px 01897 delta = (par%rhos-par%rho)/par%rho 01898 ulocalold = s%uu 01899 ulocal = s%uu 01900 philocal = phirad 01901 umeanupdphi = 0.d0 01902 uvarupdphi = 0.d0 01903 ustar = 0.d0 01904 ! 01905 ! find water depth for which kh(based on Trep) ~ 0.1 01906 khlim = 0.01d0*par%Trep**2*par%g/4/par%px**2 01907 ! 01908 ! Angle of repose 01909 reposerad = par%reposeangle*par%px/180 01910 reposedzdx = tan(reposerad) 01911 ! 01912 ! 01913 do jg=1,par%ngd 01914 if(par%thetcr<0.d0) then 01915 dstar = (par%g*(par%rhos/par%rho-1)/1.d-6/1.d-6)**(1.d0/3)*par%D50(jg) 01916 shieldscrit(jg) = 0.3d0/(1+1.2d0*dstar)+0.055d0*(1-exp(-0.02d0*dstar)) 01917 else 01918 shieldscrit(jg) = par%thetcr 01919 endif 01920 enddo 01921 endif 01922 01923 ! radial velocity of representative wave 01924 omegap = 2*par%px/par%Trep 01925 01926 ! compute local filtered velocity and acceleration term 01927 Tsmooth = par%Trep/20 01928 factime = min(par%dt/Tsmooth,1.d0) 01929 ulocal = (1-factime)*ulocal + factime*s%uu 01930 !ulocal = uu 01931 where(s%wetu==1) 01932 dudtsmooth = (ulocal-ulocalold)/par%dt 01933 elsewhere 01934 dudtsmooth = 0.d0 01935 endwhere 01936 ulocalold = ulocal 01937 ! 01938 ! calculate vertical distribution for turbulence kturb (less turbulence at bottom for larger waterdepth) 01939 if(par%lwt==1 .and. par%yturb>0.d0) then 01940 dcfinl = exp(min(100.d0,(s%hh)/max(par%facthr*s%rolthick,0.01d0))) 01941 dcfl = min(1.d0,1.d0/(dcfinl-1.d0)) 01942 dcfl = max(0.d0,dcfl) 01943 endif 01944 01945 Tsmooth = par%Trep*5 01946 factime = min(par%dt/Tsmooth,1.d0) 01947 01948 umeanupd = (1.d0-factime)*umeanupd + factime * ulocal 01949 uvarupd = (1.d0-factime)*uvarupd + factime * (ulocal-umeanupd)**2 01950 01951 if (par%sedfricfac==SEDFRICFAC_NIELSEN) then 01952 Arms = sqrt(2.d0)/omegap*sqrt(uvarupd) 01953 endif 01954 01955 do jg = 1,par%ngd 01956 ! compute sediment friction factor term 01957 select case (par%sedfricfac) 01958 case (SEDFRICFAC_NIELSEN) 01959 where(s%wetu==1) 01960 fsed = exp(5.5d0*(2.5d0*s%D50(jg)/Arms)**0.2d0-6.3d0) 01961 elsewhere 01962 fsed=0.d0 01963 endwhere 01964 fsed = min(fsed,0.05) 01965 fsed = max(fsed,s%cf) 01966 case (SEDFRICFAC_SWART) 01967 where (s%wetu==1) 01968 fsed = exp(5.213d0*(2.5d0/par%Arms*s%D50(jg))**(0.194)-5.977) 01969 elsewhere 01970 fsed = 0.d0 01971 endwhere 01972 case (SEDFRICFAC_FLOWFRIC) 01973 fsed = s%cf 01974 case(SEDFRICFAC_WILSON) 01975 fsed = 0.114d0*(par%Arms/(par%g*delta*par%Trep**2))*0.4d0 01976 case(SEDFRICFAC_CONSTANT) 01977 fsed = par%fsed 01978 end select 01979 ! 01980 ! compute boundary layer velocity 01981 if (par%phaselag==1) then 01982 where(s%wetu==1) 01983 ! add turbulent term to ustar 01984 ustar = sqrt(fsed/2)*(cos(philocal)*ulocal + & 01985 sin(philocal)/omegap*dudtsmooth) 01986 elsewhere 01987 ustar = 0.d0 01988 endwhere 01989 else 01990 where(s%wetu==1) 01991 ! add turbulent term to ustar 01992 ustar = sqrt(fsed/2)*ulocal 01993 elsewhere 01994 ustar = 0.d0 01995 endwhere 01996 endif 01997 ! 01998 ! Add turbulent stress 01999 if(par%lwt==1 .and. par%yturb>0.d0) then 02000 where(s%wetu==1) 02001 ustar = ustar + sqrt(fsed/2)*(2*sqrt(s%kturb)*dcfl*par%yturb)*sign(1.d0,ustar) 02002 endwhere 02003 endif 02004 ! 02005 ! compute shields parameter 02006 where(s%wetu==1) 02007 shields = ustar**2/(delta*par%g*s%D50(jg)) 02008 elsewhere 02009 shields = 0.d0 02010 endwhere 02011 ! 02012 ! compute bed slope effect 02013 if (par%slopecorr==SLOPECORR_NIELSEN) then 02014 where(s%wetu==1) 02015 where (s%dzbdx>0.d0) 02016 shields = max(shields/cos(min(atan(s%dzbdx),reposerad))-min(s%dzbdx,reposedzdx)*sign(1.d0,ustar),0.d0) 02017 elsewhere(s%dzbdx<0.d0) 02018 shields = max(shields/cos(max(atan(s%dzbdx),-reposerad))-max(s%dzbdx,-reposedzdx)*sign(1.d0,ustar),0.d0) 02019 endwhere 02020 endwhere 02021 elseif (par%slopecorr==SLOPECORR_FREDSOE_DEIGAARD) then 02022 where(s%wetu==1) 02023 where (s%dzbdx>0.d0) 02024 shields = shields*cos(atan(min(s%dzbdx,reposerad)))* & 02025 max(1.d0-sign(1.d0,ustar)*min(s%dzbdx/reposedzdx,1.d0),0.d0) 02026 elsewhere(s%dzbdx<0.d0) 02027 shields = shields*cos(atan(max(s%dzbdx,-reposerad)))* & 02028 max(1.d0-sign(1.d0,ustar)*max(s%dzbdx/reposedzdx,-1.d0),0.d0) 02029 02030 endwhere 02031 endwhere 02032 endif 02033 02034 ! compute streaming effect 02035 if(par%streaming==1) then 02036 ! Note assumes wave propagation is in direction of positive s. Modify to negative 02037 ! contribution in case wave direction is in negative s direction 02038 where(s%wetu==1) 02039 where(uvarupd>1d0*abs(umeanupd)) 02040 fe = exp(5.5d0*(min(170*sqrt(max(shields-0.05d0,0.d0))*s%D50(jg),s%hh)/Arms)**0.2-6.3d0) 02041 elsewhere(uvarupd<0.25d0*abs(umeanupd)) 02042 fe = 0.d0 02043 elsewhere 02044 fe = ((uvarupd/abs(umeanupd))-0.25d0)/0.75d0 * & 02045 exp(5.5d0*(min(170*sqrt(max(shields-0.05d0,0.d0))*s%D50(jg),s%hh)/Arms)**0.2-6.3d0) 02046 endwhere 02047 02048 shields = shields + (2d0/3/par%px*fe*Arms**3*omegap**3/(par%g*s%hh)) / & 02049 (delta*par%g*s%D50(jg)) * & 02050 sign(1.d0,ustar) 02051 shields = max(shields,0.d0) 02052 endwhere 02053 endif 02054 02055 02056 ! compute sediment transport 02057 where(s%wetu==1 .and. shields>shieldscrit(jg)) 02058 qsedu = (par%Ctrans*(shields-shieldscrit(jg))*sqrt(shields))* & 02059 sqrt(delta*par%g*s%D50(jg)**3)*sign(1.d0,ustar) 02060 elsewhere 02061 qsedu = 0.d0 02062 endwhere 02063 02064 !qsedu = min(qsedu,ustar*100*D50(jg)*(1.d0-par%por)) 02065 ! minimum porosity ~0.60 for fluidized bed 02066 where(qsedu>0.d0) 02067 qsedu = min(qsedu,(1.d0-0.60d0)*(abs(s%qx))) 02068 elsewhere(qsedu<0.d0) 02069 qsedu = max(qsedu,(1.d0-0.60d0)*(-abs(s%qx))) 02070 endwhere 02071 02072 02073 if(par%thetanum<1.d0) then 02074 do i=2,s%nx 02075 s%Subg(i,:,jg) = (1.d0-par%thetanum)/2*(qsedu(i-1,:)+qsedu(i+1,:)) + & 02076 par%thetanum * qsedu(i,:) 02077 enddo 02078 if (xmpi_istop) then 02079 s%Subg(1,:,jg) = qsedu(i,:) 02080 endif 02081 if (xmpi_isbot) then 02082 s%Subg(s%nx+1,:,jg) = qsedu(s%nx+1,:) 02083 endif 02084 else 02085 s%Subg(:,:,jg) = qsedu 02086 endif 02087 02088 enddo 02089 02090 end subroutine Nielsen2006 02091 02092 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02093 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02094 subroutine mccall_vanrijn(s,par) 02095 02096 use params, only: parameters 02097 use spaceparams 02098 use xmpi_module 02099 use math_tools 02100 use paramsconst 02101 02102 IMPLICIT NONE 02103 02104 type(spacepars),target :: s 02105 type(parameters) :: par 02106 02107 real*8 :: omegap 02108 real*8,save :: phirad,delta,khlim,reposerad,reposedzdx 02109 02110 integer :: i,j,jg 02111 02112 real*8,dimension(:,:),allocatable,save :: dudtsmooth 02113 real*8,dimension(:,:),allocatable,save :: fsed 02114 real*8,dimension(:,:),allocatable,save :: Arms,umeanupd,uvarupd 02115 real*8,dimension(:,:),allocatable,save :: umeanupdphi,uvarupdphi 02116 real*8,dimension(:,:),allocatable,save :: shields,qsedu,qsedutemp,dist 02117 real*8,dimension(:,:),allocatable,save :: blphi,facbl,facrw,facslp,facrwf 02118 real*8,dimension(:,:),allocatable,save :: ulocal,ulocalold,philocal 02119 real*8,dimension(:,:),allocatable,save :: dcfinl,dcfl,cffac 02120 real*8,dimension(:) ,allocatable,save :: shieldscrit,dstar 02121 real*8,dimension(:,:),allocatable,save :: signShields,thetacrlocal 02122 real*8,dimension(:,:),allocatable,save :: phishields,nEF 02123 real*8,dimension(:,:),allocatable,save :: dzbdxf 02124 02125 real*8 :: Te,kvis,Sster,cc1,cc2,wster 02126 real*8 , dimension(:),allocatable,save :: w 02127 02128 if (.not. allocated(dudtsmooth)) then 02129 allocate(dudtsmooth(s%nx+1,s%ny+1)) 02130 allocate(fsed(s%nx+1,s%ny+1)) 02131 allocate(shields(s%nx+1,s%ny+1)) 02132 allocate(qsedu(s%nx+1,s%ny+1)) 02133 allocate(qsedutemp(s%nx+1,s%ny+1)) 02134 allocate(dist(s%nx+1,s%nx+1)) 02135 allocate (blphi (s%nx+1,s%ny+1)) 02136 allocate (facbl (s%nx+1,s%ny+1)) 02137 allocate (facrw (s%nx+1,s%ny+1)) 02138 allocate (facrwf(s%nx+1,s%ny+1)) 02139 allocate (facslp (s%nx+1,s%ny+1)) 02140 allocate (ulocal (s%nx+1,s%ny+1)) 02141 allocate (ulocalold (s%nx+1,s%ny+1)) 02142 allocate(philocal(s%nx+1,s%ny+1)) 02143 allocate(umeanupdphi(s%nx+1,s%ny+1)) 02144 allocate(uvarupdphi(s%nx+1,s%ny+1)) 02145 allocate(dcfinl(s%nx+1,s%ny+1)) 02146 allocate(dcfl(s%nx+1,s%ny+1)) 02147 allocate(cffac(s%nx+1,s%ny+1)) 02148 cffac = 0.d0 02149 allocate(Arms(s%nx+1,s%ny+1)) 02150 allocate(umeanupd(s%nx+1,s%ny+1)) 02151 allocate(uvarupd(s%nx+1,s%ny+1)) 02152 umeanupd = 0.d0 02153 uvarupd = 0.d0 02154 allocate(signShields(s%nx+1,s%ny+1)) 02155 signShields = 0.d0 02156 allocate(thetacrlocal(s%nx+1,s%ny+1)) 02157 thetacrlocal = par%thetcr 02158 allocate(shieldscrit(par%ngd)) 02159 allocate(dstar(par%ngd)) 02160 allocate(dzbdxf(s%nx+1,s%ny+1)) 02161 02162 if (par%form==FORM_WILCOCK_CROW) then 02163 allocate(phishields(s%nx+1,s%ny+1)) 02164 elseif (par%form==FORM_ENGELUND_FREDSOE) then 02165 allocate(nEF(s%nx+1,s%ny+1)) 02166 endif 02167 02168 if(par%bulk==1) then 02169 Te = 20.d0 02170 kvis = 4.d0/(20.d0+Te)*1d-5 ! Van rijn, 1993 02171 allocate(w(par%ngd)) 02172 do jg=1,par%ngd 02173 Sster = s%D50(jg)/(4*kvis)*sqrt((par%rhos/par%rho-1)*par%g*s%D50(jg)) 02174 cc1 = 1.06d0*tanh(0.064d0*Sster*exp(-7.5d0/Sster**2)) 02175 cc2 = 0.22d0*tanh(2.34d0*Sster**(-1.18d0)*exp(-0.0064d0*Sster**2)) 02176 wster = cc1+cc2*Sster 02177 w(jg) = wster*sqrt((par%rhos/par%rho-1.d0)*par%g*s%D50(jg)) 02178 enddo 02179 endif 02180 02181 fsed = 0.d0 02182 phirad = par%phit/180*par%px 02183 delta = (par%rhos-par%rho)/par%rho 02184 ulocalold = s%uu 02185 ulocal = s%uu 02186 philocal = phirad 02187 umeanupdphi = 0.d0 02188 uvarupdphi = 0.d0 02189 ! 02190 ! find water depth for which kh(based on Trep) ~ 0.1 02191 khlim = 0.01d0*par%Trep**2*par%g/4/par%px**2 02192 ! 02193 ! Angle of repose 02194 reposerad = par%reposeangle*par%px/180 02195 reposedzdx = tan(reposerad) 02196 do i=1,s%nx+1 02197 dist(:,i) = abs(s%xu(i,1)-s%xu(:,1)) 02198 dist(:,i) = dist(:,i)/0.25d0 02199 dist(:,i) = max(dist(:,i),1.d0) 02200 dist(:,i) = 1.d0-dist(:,i) 02201 enddo 02202 02203 do jg=1,par%ngd 02204 dstar(jg) = (par%g*(par%rhos/par%rho-1)/1.d-6/1.d-6)**(1.d0/3)*par%D50(jg) 02205 if(par%thetcr<0.d0) then 02206 shieldscrit(jg) = 0.3d0/(1+1.2d0*dstar(jg))+0.055d0*(1-exp(-0.02d0*dstar(jg))) 02207 else 02208 shieldscrit(jg) = par%thetcr 02209 endif 02210 enddo 02211 endif 02212 02213 02214 !do j=1,s%ny+1 02215 ! do i=1,nx 02216 ! Lloc = par%Trep*sqrt(par%g*max(0.1d0,hh(i,j)))/8 02217 ! irange1 = max(1, i-nint(Lloc/dsu(i,j)))! staggered grid means lower should be at least zb(i) 02218 ! irange2 = min(s%nx+1,i+nint(Lloc/dsu(i,j))) 02219 ! irange2 = max(i+1,irange2) ! staggered grid means upper should be at least zb(i+1) 02220 ! dzbdxf(i,j) = (zb(irange2,j)-zb(irange1,j))/(sdist(irange2,j)-sdist(irange1,j)) 02221 ! enddo 02222 !enddo 02223 !dzbdxf(s%nx+1,:) = dzbdxf(nx,:) 02224 dzbdxf = s%dzbdx 02225 02226 do jg = 1,par%ngd 02227 02228 ! compute shields parameter 02229 02230 if (par%gwflow==1 .and. par%inclrelweight==1) then 02231 !facrw = 0.5d0*max(infil/Kz,-1.d0) 02232 facrw = 0.5d0*s%infil/s%Kzinf 02233 else 02234 facrw = 0.d0 02235 endif 02236 02237 where(s%wetu==1) 02238 ! try adding (groundwater) head gradient 02239 shields = (abs(s%taubx-par%incldzdx*s%dzsdx*par%rho*par%g*s%D50(jg))) /(par%rho*par%g*s%D50(jg)*max(delta+facrw,1e-6)) 02240 signShields = sign(1.d0,s%taubx-par%incldzdx*s%dzsdx*par%rho*par%g*s%D50(jg)) 02241 elsewhere 02242 shields = 0.d0 02243 signShields = 0.d0 02244 endwhere 02245 ! 02246 ! compute bed slope effect 02247 if (par%slopecorr==SLOPECORR_NIELSEN) then 02248 where(s%wetu==1) 02249 where (s%dzbdx>0.d0) 02250 shields = max(shields/cos(min(atan(dzbdxf),reposerad))-min(dzbdxf,reposedzdx)*signShields,0.d0) 02251 elsewhere(s%dzbdx<0.d0) 02252 shields = max(shields/cos(max(atan(dzbdxf),-reposerad))-max(dzbdxf,-reposedzdx)*signShields,0.d0) 02253 endwhere 02254 endwhere 02255 elseif (par%slopecorr==SLOPECORR_FREDSOE_DEIGAARD) then 02256 where(s%wetu==1) 02257 where (s%dzbdx>0.d0) 02258 shields = shields*cos(atan(min(dzbdxf,reposerad)))* & 02259 max(1.d0-signShields*min(dzbdxf/reposedzdx,1.d0),0.d0) 02260 elsewhere(s%dzbdx<0.d0) 02261 shields = shields*cos(atan(max(dzbdxf,-reposerad)))* & 02262 max(1.d0-signShields*max(dzbdxf/reposedzdx,-1.d0),0.d0) 02263 endwhere 02264 endwhere 02265 endif 02266 02267 !! compute streaming effect 02268 !if(par%streaming==1) then 02269 ! ! Note assumes wave propagation is in direction of positive s. Modify to negative 02270 ! ! contribution in case wave direction is in negative s direction 02271 ! Arms = sqrt(2.d0)/omegap*sqrt(uvarupd) 02272 ! where(s%wetu==1) 02273 ! where(uvarupd>1d0*abs(umeanupd)) 02274 ! fe = exp(5.5d0*(min(170*sqrt(max(shields-0.05d0,0.d0))*s%D50(jg),s%hh)/Arms)**0.2-6.3d0) 02275 ! elsewhere(uvarupd<0.25d0*abs(umeanupd)) 02276 ! fe = 0.d0 02277 ! elsewhere 02278 ! fe = ((uvarupd/abs(umeanupd))-0.25d0)/0.75d0 * & 02279 ! exp(5.5d0*(min(170*sqrt(max(shields-0.05d0,0.d0))*s%D50(jg),s%hh)/Arms)**0.2-6.3d0) 02280 ! endwhere 02281 ! 02282 ! shields = shields + (2d0/3/par%px*fe*Arms**3*omegap**3/(par%g*s%hh)) / & 02283 ! ((delta+facrw)*par%g*s%D50(jg)) * & 02284 ! signShields 02285 ! shields = max(shields,0.d0) 02286 ! endwhere 02287 !endif 02288 02289 thetacrlocal = shieldscrit(jg) 02290 02291 ! compute sediment transport 02292 select case (par%form) 02293 case (FORM_MPM) 02294 par%Ctrans = 8.d0 02295 where(s%wetu==1 .and. shields>thetacrlocal) 02296 qsedu = (par%Ctrans*(shields-thetacrlocal)**1.5d0)* & 02297 sqrt(delta*par%g*s%D50(jg)**3)*signShields 02298 elsewhere 02299 qsedu = 0.d0 02300 endwhere 02301 case (FORM_WONG_PARKER) 02302 par%Ctrans = 3.97d0 02303 where(s%wetu==1 .and. shields>thetacrlocal) 02304 qsedu = (par%Ctrans*(shields-thetacrlocal)**1.5d0)* & 02305 sqrt(delta*par%g*s%D50(jg)**3)*signShields 02306 elsewhere 02307 qsedu = 0.d0 02308 endwhere 02309 case (FORM_FL_VB) ! Fernandez Luque, R., and van Beek, R.(1976). Erosion and Transport of Bed-Load 02310 ! Sediment. J. Hydraul, Res., 14(2), 127-144 02311 par%Ctrans = 5.7d0 02312 where(s%wetu==1 .and. shields>thetacrlocal) 02313 qsedu = (par%Ctrans*(shields-thetacrlocal)**1.5d0)* & 02314 sqrt(delta*par%g*s%D50(jg)**3)*signShields 02315 elsewhere 02316 qsedu = 0.d0 02317 endwhere 02318 case (FORM_WILCOCK_CROW) 02319 where(s%wetu==1) 02320 phishields = shields/thetacrlocal 02321 where(phishields>=1.35d0) 02322 qsedu = 14*(1.d0-0.894d0/sqrt(phishields))**4.5d0*shields**1.5*sqrt(delta*par%g)*s%D50(jg)**1.5*signShields 02323 elsewhere 02324 qsedu = 0.002d0*phishields**7.5d0*shields**1.5*sqrt(delta*par%g)*s%D50(jg)**1.5*signShields 02325 endwhere 02326 elsewhere 02327 qsedu = 0.d0 02328 endwhere 02329 case (FORM_ENGELUND_FREDSOE) 02330 where(s%wetu==1 .and. shields>thetacrlocal) 02331 ! note: pi/6 ~ 0.5236, dynamic friction ~ 0.5-0.65 (Fredsoe & Deigaard) 02332 nEF = (1.d0+(0.5236d0*0.5d0/(shields-thetacrlocal))**4)**-0.25d0 02333 qsedu = 5*nEF*(sqrt(shields)-0.7d0*sqrt(thetacrlocal))*sqrt(delta*par%g*s%D50(jg)**3)*signShields 02334 elsewhere 02335 qsedu = 0.d0 02336 endwhere 02337 case (FORM_FREDSOE_DEIGAARD) ! Equation 7.59 02338 where(s%wetu==1 .and. shields>thetacrlocal) 02339 ! note: 30/pi = 9.5493, mu = 0.65 -> 30/pi/mu = 14.6912 02340 qsedu = 14.6912d0*(shields-thetacrlocal)*(sqrt(shields)-0.7d0*sqrt(thetacrlocal)) * & 02341 sqrt(delta*par%g*s%D50(jg)**3)*signShields 02342 elsewhere 02343 qsedu = 0.d0 02344 endwhere 02345 case(FORM_MCCALL_VANRIJN) ! Eq 10. note: devision by rhos to get m2/s transport rate 02346 par%Ctrans = 0.5d0 02347 where(s%wetu==1 .and. shields>thetacrlocal) 02348 qsedu = par%Ctrans*s%D50(jg)*dstar(jg)**(-0.3d0)*sqrt(abs(s%taubx)/par%rho)* & 02349 ((shields-thetacrlocal)/thetacrlocal)*signShields 02350 elsewhere 02351 qsedu = 0.d0 02352 endwhere 02353 end select 02354 02355 02356 where(qsedu>0.d0) 02357 qsedu = qsedu * par%uprushfac 02358 elsewhere 02359 qsedu = qsedu * par%backwashfac 02360 endwhere 02361 02362 !qsedu = min(qsedu,ustar*100*D50(jg)*(1.d0-par%por)) 02363 ! minimum porosity ~0.60 for fluidized bed 02364 where(qsedu>0.d0) 02365 qsedu = min(qsedu,(1.d0-0.60d0)*(abs(s%qx))) 02366 elsewhere(qsedu<0.d0) 02367 qsedu = max(qsedu,(1.d0-0.60d0)*(-abs(s%qx))) 02368 endwhere 02369 02370 if (par%bulk==0) then 02371 if(par%thetanum<1.d0) then 02372 do i=2,s%nx 02373 s%Subg(i,:,jg) = (1.d0-par%thetanum)/2*(qsedu(i-1,:)+qsedu(i+1,:)) + & 02374 par%thetanum * qsedu(i,:) 02375 enddo 02376 if(xmpi_istop) s%Subg(1,:,jg) = qsedu(i,:) 02377 if(xmpi_isbot) s%Subg(s%nx+1,:,jg) = qsedu(s%nx+1,:) 02378 else 02379 s%Subg(:,:,jg) = qsedu 02380 endif 02381 ! To Do: fix this properly for MPI 02382 do j=1,s%ny+1 02383 do i=1,s%nx+1 02384 if(s%Subg(i,j,jg)>0.d0) then 02385 s%Subg(i,j,jg) = s%Subg(i,j,jg)*s%sedcal(jg)*s%pbbed(i,j,1,jg) 02386 else 02387 s%Subg(i,j,jg) = s%Subg(i,j,jg)*s%sedcal(jg)*s%pbbed(min(i+1,s%nx+1),j,1,jg) 02388 endif 02389 enddo 02390 enddo 02391 else 02392 if (par%oldTsmin==1) then 02393 s%Tsg(:,:,jg) = max(par%tsfac*s%hu/w(jg),par%Tsmin) 02394 else 02395 s%Tsg(:,:,jg) = max(par%tsfac*s%hu/w(jg),par%dtlimTs*par%dt) 02396 endif 02397 !s%Tsg(:,:,jg) = max(par%tsfac*s%hu/w(jg),par%Tsmin) 02398 s%ceqsg(:,:,jg) = qsedu/s%hu/s%uu 02399 s%ceqbg(:,:,jg) = 0.d0 02400 endif 02401 enddo 02402 02403 end subroutine mccall_vanrijn 02404 02405 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02406 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02407 02408 02409 subroutine waveturb(s,par) 02410 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02411 ! Copyright (C) 2007 UNESCO-IHE, WL|Delft Hydraulics and Delft University ! 02412 ! Dano Roelvink, Ap van Dongeren, Ad Reniers, Jamie Lescinski, ! 02413 ! Jaap van Thiel de Vries, Robert McCall ! 02414 ! ! 02415 ! d.roelvink@unesco-ihe.org ! 02416 ! UNESCO-IHE Institute for Water Education ! 02417 ! P.O. Box 3015 ! 02418 ! 2601 DA Delft ! 02419 ! The Netherlands ! 02420 ! ! 02421 ! This library is free software; you can redistribute it and/or ! 02422 ! modify it under the terms of the GNU Lesser General Public ! 02423 ! License as published by the Free Software Foundation; either ! 02424 ! version 2.1 of the License, or (at your option) any later version. ! 02425 ! ! 02426 ! This library is distributed in the hope that it will be useful, ! 02427 ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! 02428 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 02429 ! Lesser General Public License for more details. ! 02430 ! ! 02431 ! You should have received a copy of the GNU Lesser General Public ! 02432 ! License along with this library; if not, write to the Free Software ! 02433 ! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ! 02434 ! USA ! 02435 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02436 use params, only: parameters 02437 use spaceparams 02438 use xmpi_module 02439 use paramsconst, only: TURBADV_EULERIAN, TURBADV_LAGRANGIAN, TURBADV_NONE 02440 02441 implicit none 02442 02443 type(spacepars),target :: s 02444 type(parameters) :: par 02445 02446 integer :: i 02447 integer :: j 02448 real*8 :: ML, disturb 02449 real*8, save :: twothird 02450 real*8,dimension(:,:),allocatable,save :: ksource, kturbu,kturbv,Sturbu,Sturbv,dzsdt_cr 02451 02452 !include 's.ind' 02453 !include 's.inp' 02454 02455 if (.not. allocated(kturbu)) then 02456 allocate(ksource (s%nx+1,s%ny+1)) 02457 allocate(kturbu (s%nx+1,s%ny+1)) 02458 allocate(kturbv (s%nx+1,s%ny+1)) 02459 allocate(Sturbu (s%nx+1,s%ny+1)) 02460 allocate(Sturbv (s%nx+1,s%ny+1)) 02461 allocate(dzsdt_cr (s%nx+1,s%ny+1)) 02462 twothird=2.d0/3.d0 02463 endif 02464 ! use lagrangian velocities 02465 kturbu = 0.0d0 !Jaap 02466 kturbv = 0.0d0 !Jaap 02467 ! dzsdt_cr=par%beta*s%c 02468 dzsdt_cr=par%beta*sqrt(par%g*s%hh) 02469 ! Update roller thickness 02470 !s%rolthick=s%rolthick+par%dt*(abs(s%dzsdt)-dzsdt_cr) Dano: not abs! 02471 s%rolthick=s%rolthick+par%dt*(s%dzsdt-dzsdt_cr) 02472 s%rolthick=max(s%rolthick,0.d0) 02473 s%rolthick=min(s%rolthick,s%hh) 02474 where (s%wetz==0) 02475 s%rolthick=0.d0 02476 endwhere 02477 02478 ! Jaap compute sources and sinks 02479 ! long wave source 02480 ksource = 0 02481 if (par%lwt == 1) then 02482 ksource = par%g*s%rolthick*par%beta*sqrt(par%g*s%hh) !only important in shallow water, where s%c=sqrt(gh) 02483 endif 02484 if (par%turbadv == TURBADV_NONE) then 02485 s%kturb = (s%DR/par%rho)**twothird ! See Battjes, 1975 / 1985 02486 else 02487 ksource = ksource + s%DR/par%rho 02488 02489 02490 ! Jaap do long wave turb approach for both short waves and long waves 02491 ! 02492 ! Turbulence in uu-points 02493 ! 02494 do j=1,s%ny+1 02495 do i=1,s%nx 02496 if(s%uu(i,j)>0.d0) then 02497 kturbu(i,j)=par%thetanum*s%kturb(i,j)+(1.d0-par%thetanum)*s%kturb(min(i+1,s%nx),j) 02498 elseif(s%uu(i,j)<0.d0) then 02499 kturbu(i,j)=par%thetanum*s%kturb(i+1,j)+(1.d0-par%thetanum)*s%kturb(max(i,2),j) 02500 else 02501 kturbu(i,j)=0.5d0*(s%kturb(i,j)+s%kturb(i+1,j)) 02502 endif 02503 enddo 02504 enddo 02505 if (xmpi_isbot) kturbu(s%nx+1,:) = s%kturb(s%nx+1,:) 02506 ! 02507 ! Turbulence in vv-points 02508 ! 02509 do j=1,s%ny 02510 do i=1,s%nx+1 02511 if(s%vv(i,j)>0) then 02512 kturbv(i,j)=par%thetanum*s%kturb(i,j)+(1.d0-par%thetanum)*s%kturb(i,min(j+1,s%ny)) 02513 else if(s%vv(i,j)<0) then 02514 kturbv(i,j)=par%thetanum*s%kturb(i,j+1)+(1.d0-par%thetanum)*s%kturb(i,max(j,2)) 02515 else 02516 kturbv(i,j)=0.5d0*(kturbv(i,j)+kturbv(i,j+1)) 02517 endif 02518 enddo 02519 enddo 02520 kturbv(:,s%ny+1) = s%kturb(:,s%ny+1) !Robert 02521 ! 02522 ! Turbulence advection in X and Y direction 02523 ! 02524 if (par%turbadv == TURBADV_LAGRANGIAN) then 02525 Sturbu=kturbu*s%uu*s%hu*s%wetu 02526 Sturbv=kturbv*s%vv*s%hv*s%wetv 02527 elseif (par%turbadv == TURBADV_EULERIAN) then 02528 Sturbu=kturbu*s%ueu*s%hu*s%wetu 02529 Sturbv=kturbv*s%vev*s%hv*s%wetv 02530 endif 02531 ! 02532 ! Update turbulence 02533 ! 02534 if (s%ny>0) then 02535 do j=2,s%ny+1 02536 do i=2,s%nx+1 02537 if (par%betad>0) then 02538 disturb=par%betad*s%kturb(i,j)**1.5d0 02539 else 02540 !ML=max(s%rolthick(i,j),0.07d0*s%hstokes(i,j)) 02541 !disturb=0.08d0*s%hstokes(i,j)/ML*s%kturb(i,j)**1.5d0 02542 endif 02543 s%kturb(i,j) = (s%hold(i,j)*s%kturb(i,j)-par%dt*( & 02544 (Sturbu(i,j)*s%dnu(i,j)-Sturbu(i-1,j)*s%dnu(i-1,j)+& 02545 Sturbv(i,j)*s%dsv(i,j)-Sturbv(i,j-1)*s%dsv(i,j-1))*s%dsdnzi(i,j)-& 02546 (ksource(i,j)-disturb)))/s%hh(i,j) 02547 s%kturb(i,j)=max(s%kturb(i,j),0.0d0) 02548 02549 enddo 02550 enddo 02551 else 02552 j=1 02553 do i=2,s%nx+1 02554 ! Robert: perhaps better to re-write to implicit sink term 02555 s%kturb(i,j) = (s%hold(i,j)*s%kturb(i,j)-par%dt*( & 02556 (Sturbu(i,j)*s%dnu(i,j)-Sturbu(i-1,j)*s%dnu(i-1,j))*s%dsdnzi(i,j)-& 02557 (ksource(i,j)-par%betad*s%kturb(i,j)**1.5d0)))/s%hh(i,j) 02558 s%kturb(i,j)=max(s%kturb(i,j),0.0d0) 02559 02560 enddo 02561 endif 02562 02563 !Robert: cannot divide by hh here again 02564 !s%kturb = s%kturb/s%hh !max(s%hh,0.01d0) : 02565 02566 ! Jaap only required for advection mode? 02567 if (xmpi_istop) s%kturb(1,:)=s%kturb(2,:) 02568 if (xmpi_isbot) s%kturb(s%nx+1,:)=s%kturb(s%nx+1-1,:) 02569 if (s%ny>0) then 02570 if (xmpi_isleft) s%kturb(:,1)=s%kturb(:,2) 02571 if (xmpi_isright) s%kturb(:,s%ny+1)=s%kturb(:,s%ny+1-1) 02572 endif 02573 02574 #ifdef USEMPI 02575 call xmpi_shift_ee(s%kturb) 02576 #endif 02577 02578 endif ! turbadv == 'none' 02579 02580 end subroutine waveturb 02581 02582 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02583 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02584 02585 02586 subroutine RvR(s,par) 02587 02588 use params, only: parameters 02589 use spaceparams 02590 use xmpi_module 02591 02592 implicit none 02593 02594 type(spacepars),target :: s 02595 type(parameters) :: par 02596 02597 real*8 , save :: m1,m2,m3,m4,m5,m6,alpha,beta 02598 02599 real*8 , dimension(:,:),allocatable,save :: Urs,Bm,B1 02600 02601 !include 's.ind' 02602 !include 's.inp' 02603 02604 ! only in first timestep.. 02605 if (.not. allocated(Urs)) then 02606 02607 allocate (Urs (s%nx+1,s%ny+1)) 02608 allocate (Bm (s%nx+1,s%ny+1)) 02609 allocate (B1 (s%nx+1,s%ny+1)) 02610 02611 m1 = 0; ! a = 0 02612 m2 = 0.7939; ! b = 0.79 +/- 0.023 02613 m3 = -0.6065; ! c = -0.61 +/- 0.041 02614 m4 = 0.3539; ! d = -0.35 +/- 0.032 02615 m5 = 0.6373; ! e = 0.64 +/- 0.025 02616 m6 = 0.5995; ! f = 0.60 +/- 0.043 02617 alpha = -log10(exp(1.d0))/m4 02618 beta = exp(m3/m4) 02619 02620 endif 02621 02622 Urs = 3.d0/8.d0*sqrt(2.d0)*s%H*s%k/(s%k*s%hh)**3 !Ursell number 02623 Urs = max(Urs,0.000000000001d0) 02624 Bm = m1 + (m2-m1)/(1.d0+beta*Urs**alpha) !Boltzmann sigmoid (eq 6) 02625 B1 = (-90.d0+90.d0*tanh(m5/Urs**m6))*par%px/180.d0 02626 s%Sk = Bm*cos(B1) !Skewness (eq 8) 02627 s%As = Bm*sin(B1) !Asymmetry(eq 9) 02628 s%ua = par%sws*(par%facSk*s%Sk-par%facAs*s%As)*s%urms 02629 02630 ! multiply Sk and As with wetz to get zeros at h = 0 for output 02631 s%Sk = s%Sk*s%wetz 02632 s%As = s%As*s%wetz 02633 02634 end subroutine RvR 02635 02636 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02637 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02638 02639 subroutine vT(s,par) 02640 02641 use params, only: parameters 02642 use spaceparams 02643 use readkey_module 02644 use xmpi_module 02645 02646 implicit none 02647 02648 type(spacepars),target :: s 02649 type(parameters) :: par 02650 02651 integer :: i,j 02652 integer , save :: nh,nt 02653 integer :: ih0,it0,ih1,it1 02654 real*8 :: p,q,f0,f1,f2,f3 02655 real*8 :: t0fac,siguref,duddtmax,dudtmax,duddtmean,dudtmean,detadxmean 02656 real*8 , save :: dh,dt 02657 02658 real*8 , dimension(:,:),allocatable ,save :: h0,t0,detadxmax 02659 ! Robert: RF table now included in source code, rather than read from file 02660 ! Rienecker Fenton table with amongst others amplitudes non-linear components obtained with stream function theory 02661 include 'RF.inc' 02662 ! Robert: 'RF.inc' contains definition of RF as real*8(5,33,40) with "parameter" attribute 02663 ! so RF values may not be modified! To save memory, only rows 13,14,15,16 and 18 of the 02664 ! original matrix are stored. So new row 1 corresponds with old row 13, etc. 02665 02666 !include 's.ind' 02667 !include 's.inp' 02668 02669 02670 ! only in first timestep.. 02671 if (.not. allocated(h0)) then 02672 allocate (h0 (s%nx+1,s%ny+1)) 02673 allocate (t0 (s%nx+1,s%ny+1)) 02674 allocate (detadxmax (s%nx+1,s%ny+1)) 02675 dh = 0.03d0 02676 dt = 1.25d0 02677 nh = floor(0.99d0/dh); 02678 nt = floor(50.d0/dt); 02679 endif 02680 02681 ! non-linearity of short waves is listed in table as function of dimensionless wave height h0 and dimensionless wave period t0 02682 02683 ! compute dimensionless wave height and wave period in each grid point.. 02684 h0 = min(nh*dh,max(dh,min(s%H,s%hh)/s%hh)) 02685 t0 = min(nt*dt,max(dt,par%Trep*sqrt(par%g/s%hh))) 02686 02687 ! estimate Sk, As and ua by interpolating table values 02688 do j=1,s%ny+1 02689 do i=1,s%nx+1 02690 ! interpolate table values.... 02691 ih0=floor(h0(i,j)/dh); 02692 it0=floor(T0(i,j)/dt); 02693 ih1=min(ih0+1,nh); 02694 it1=min(it0+1,nt); 02695 p=(h0(i,j)-ih0*dh)/dh; 02696 q=(T0(i,j)-it0*dt)/dt; 02697 02698 f0=(1-p)*(1-q); 02699 f1=p*(1-q); 02700 f2=q*(1-p); 02701 f3=p*q; 02702 02703 ! Skewness and assymetry 02704 s%Sk(i,j) = f0*RF(1,ih0,it0)+f1*RF(1,ih1,it0)+ f2*RF(1,ih0,it1)+f3*RF(1,ih1,it1) 02705 s%As(i,j) = f0*RF(2,ih0,it0)+f1*RF(2,ih1,it0)+ f2*RF(2,ih0,it1)+f3*RF(2,ih1,it1) 02706 02707 ! Sediment advection velocity from Skewness and Assymetry 02708 ! ua(i,j) = par%sws*par%facua*(Sk(i,j)-As(i,j))*urms(i,j) 02709 s%ua(i,j) = par%sws*(par%facSk*s%Sk(i,j)-par%facAs*s%As(i,j))*s%urms(i,j) 02710 02711 ! Estimate bore period Tbore and mean slope bore front to feeded back in roller energy balance 02712 02713 ! correct slope in case 1.25>T0>50 02714 if (t0(i,j)==50.d0) then 02715 t0fac = 50.d0/max((par%Trep*sqrt(par%g/s%hh(i,j))),50.d0) 02716 elseif (t0(i,j)==1.25)then 02717 t0fac = 1.25d0/min((par%Trep*sqrt(par%g/s%hh(i,j))),1.25d0) 02718 else 02719 t0fac = 1.d0 02720 endif 02721 02722 ! detadxmax for Tbore... 02723 ! dimnesionless maximum acceleration under bore front 02724 duddtmax = f0*RF(3,ih0,it0)+f1*RF(3,ih1,it0)+ f2*RF(3,ih0,it1)+f3*RF(3,ih1,it1) 02725 siguref = f0*RF(4,ih0,it0)+f1*RF(4,ih1,it0)+ f2*RF(4,ih0,it1)+f3*RF(4,ih1,it1) 02726 ! translate dimensionless duddtmax to real world dudtmax 02727 ! /scale with variance and go from [-] to [m/s^2] /tableb./dimensionless dudtmax 02728 dudtmax = s%urms(i,j)/max(par%eps,siguref)*sqrt(par%g/s%hh(i,j))*t0fac*duddtmax 02729 detadxmax(i,j) = dudtmax*sinh(s%k(i,j)*s%hh(i,j))/max(max(s%c(i,j),sqrt(s%H(i,j)*par%g)),1d-10)/s%sigm(i,j) 02730 02731 ! detadxmean for roller energy balance dissipation... 02732 if (par%rfb==1) then 02733 duddtmean = f0*RF(5,ih0,it0)+f1*RF(5,ih1,it0)+ f2*RF(5,ih0,it1)+f3*RF(5,ih1,it1) 02734 dudtmean = s%urms(i,j)/max(par%eps,siguref)*sqrt(par%g/s%hh(i,j))*t0fac*duddtmean 02735 detadxmean = dudtmean*sinh(s%k(i,j)*s%hh(i,j))/max(s%c(i,j),sqrt(s%H(i,j)*par%g))/s%sigm(i,j) 02736 s%BR(i,j) = par%BRfac*sin(atan(detadxmean)) 02737 endif 02738 02739 enddo 02740 enddo 02741 02742 s%Tbore = max(par%Trep/25.d0,min(par%Trep/4.d0,s%H/(max(max(s%c,sqrt(s%H*par%g)),1d-10)*max(detadxmax,par%eps)))) 02743 s%Tbore = par%Tbfac*s%Tbore 02744 02745 ! multiply Sk and As with wetz to get zeros at h = 0 for output 02746 s%Sk = s%Sk*s%wetz 02747 s%As = s%As*s%wetz 02748 02749 end subroutine vT 02750 02751 subroutine setbathy_update(s, par) 02752 02753 use params, only: parameters 02754 use spaceparams 02755 use interp, only: linear_interp 02756 02757 implicit none 02758 02759 type(spacepars) :: s 02760 type(parameters) :: par 02761 02762 integer :: i,j,dummy 02763 real*8,dimension(s%nx+1,s%ny+1) :: zbnew 02764 02765 ! interpolate from file 02766 do j=1,s%ny+1 02767 do i=1,s%nx+1 02768 call LINEAR_INTERP(s%tsetbathy,s%setbathy(i,j,:),par%nsetbathy, & 02769 par%t,zbnew(i,j),dummy) 02770 enddo 02771 enddo 02772 ! update water level 02773 s%zs = s%zs+zbnew-s%zb 02774 ! update bed level 02775 s%zb = zbnew 02776 s%hh=max(s%zs-s%zb,par%eps) 02777 ! update wet and dry cells 02778 where (s%hh>par%eps) 02779 s%wetz=1 02780 elsewhere 02781 s%wetz=0 02782 s%zs = s%zb+par%eps 02783 s%hh = par%eps 02784 endwhere 02785 02786 end subroutine setbathy_update 02787 02788 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02789 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 02790 02791 subroutine hybrid(s,par) 02792 02793 use params, only: parameters 02794 use interp, only: linear_interp 02795 use spaceparams 02796 use xmpi_module 02797 02798 implicit none 02799 02800 type(spacepars),target :: s 02801 type(parameters) :: par 02802 02803 integer :: i,j,j1,indx,first, nIter, maxIter 02804 integer , dimension(:), allocatable,save :: slopeind 02805 real*8 , dimension(:), allocatable,save :: hav1d 02806 real*8 :: irrb,runup_old 02807 02808 !include 's.ind' 02809 !include 's.inp' 02810 02811 if (.not. allocated(hav1d)) then 02812 allocate(hav1d (s%nx+1)) 02813 allocate(slopeind (s%nx+1)) 02814 endif 02815 02816 do j=1,s%ny+1 02817 indx = s%nx+1 02818 first = 0 02819 do i=1,s%nx 02820 if (s%wetz(i,j)-s%wetz(max(i-1,1),j)==-1 .and. first==0) then ! transition from wet to dry 02821 ! only consider first dry point 02822 first = 1 02823 ! find wave height for runup at L1 meter from water line 02824 call linear_interp(s%xz(:,j),s%H(:,j),s%nx+1,s%xz(i-1,j)-s%L1(i-1,j),s%Hrunup(j),indx) 02825 ! Find toe of runup slope if present (dzbdx > 0.15). 02826 ! If not present Hrunup will converge to H at the water line (where H = 0 per definition) 02827 do j1=indx,i-1 02828 ! TODO: Strange condition. In case of no toe, or no steep slope, 02829 ! there will still be extra turbulence at L1 meter from the water line... 02830 ! cross shore location structure toe 02831 if (s%dzbdx(j1,j)<0.15d0 .or. s%structdepth(j1,j)>0.1d0) then 02832 indx = j1 02833 endif 02834 enddo 02835 ! update Hrunup and runup x-location 02836 s%Hrunup(j) = s%H(indx,j) ! short wave height at revetment toe 02837 s%xHrunup(j) = s%xz(indx,j) ! cross-shore location revetment toe 02838 s%istruct(j) = indx*1.d0 ! cross-shore index revetment toe 02839 s%iwl(j) = (i-1)*1.d0 ! cross-shore location waterline (inlcuding lw-s%runup) 02840 02841 ! now iteratively compute runup 02842 hav1d = s%hh(:,j) 02843 runup_old = huge(0.d0) 02844 s%runup(j) = 0; 02845 nIter = 0; 02846 maxIter = 50; 02847 do while (abs(s%runup(j)-runup_old)>0.01d0 .and. nIter < maxIter) 02848 nIter = nIter +1; 02849 runup_old = s%runup(j) 02850 slopeind = 0 02851 where (hav1d>par%eps .and. s%dzbdx(:,j)>0.15d0) 02852 slopeind = 1 02853 endwhere 02854 s%strucslope(j) = sum(s%dzbdx(indx:s%nx,j)*s%dsu(indx:s%nx,j)*slopeind(indx:s%nx))/ & 02855 max(par%eps,sum(s%dsu(indx:s%nx,j)*slopeind(indx:s%nx))) 02856 if (s%strucslope(j) > 0.d0) then 02857 irrb = s%strucslope(j)/sqrt(2*par%px*max(s%Hrunup(j),par%eps)/par%g/par%Trep**2) 02858 s%runup(j) = par%facrun*min(irrb,2.3d0)*s%Hrunup(j)*cos(2*par%px/par%Trep*par%t) 02859 else 02860 s%runup(j) = 0.d0; 02861 endif 02862 ! This triggers s%runup to be calculated for the complete hinterland (also behind a dune). 02863 ! Only values calculated for the first dune front are used in the avalanching algorithm (morphevolution) 02864 hav1d = s%wetz(:,j)*max(par%eps,(s%hh(:,j) + s%runup(j))) + & 02865 (1.d0-s%wetz(:,j))*max(par%eps,s%runup(j)+s%zs(i-1,j)-s%zb(:,j) ) 02866 enddo 02867 endif 02868 enddo 02869 enddo 02870 02871 02872 02873 end subroutine hybrid 02874 02875 end module morphevolution