XBeach
|
00001 module wave_stationary_directions_module 00002 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00003 ! Copyright (C) 2007 UNESCO-IHE, WL|Delft Hydraulics and Delft University ! 00004 ! Dano Roelvink, Ap van Dongeren, Ad Reniers, Jamie Lescinski, ! 00005 ! Jaap van Thiel de Vries, Robert McCall ! 00006 ! ! 00007 ! d.roelvink@unesco-ihe.org ! 00008 ! UNESCO-IHE Institute for Water Education ! 00009 ! P.O. Box 3015 ! 00010 ! 2601 DA Delft ! 00011 ! The Netherlands ! 00012 ! ! 00013 ! This library is free software; you can redistribute it and/or ! 00014 ! modify it under the terms of the GNU Lesser General Public ! 00015 ! License as published by the Free Software Foundation; either ! 00016 ! version 2.1 of the License, or (at your option) any later version. ! 00017 ! ! 00018 ! This library is distributed in the hope that it will be useful, ! 00019 ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! 00020 ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ! 00021 ! Lesser General Public License for more details. ! 00022 ! ! 00023 ! You should have received a copy of the GNU Lesser General Public ! 00024 ! License along with this library; if not, write to the Free Software ! 00025 ! Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ! 00026 ! USA ! 00027 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00028 implicit none 00029 save 00030 00031 contains 00032 00033 subroutine wave_stationary_directions(s,par,callType) 00034 use params 00035 use spaceparams 00036 use roelvink_module 00037 use wave_functions_module 00038 use xmpi_module 00039 use logging_module 00040 use paramsconst 00041 00042 IMPLICIT NONE 00043 00044 type(spacepars), target :: s 00045 type(parameters) :: par 00046 integer :: callType 00047 00048 integer,parameter :: callTypeStationary = 0 00049 integer,parameter :: callTypeDirections = 1 00050 00051 integer :: i,imax,i1 00052 integer :: j 00053 integer :: itheta,iter,itermax 00054 integer :: ntheta_local 00055 integer,save :: scheme_local,scheme_local_yadvec 00056 real*8 , dimension(:,:) ,allocatable,save :: dhdx,dhdy,dudx,dudy,dvdx,dvdy 00057 real*8 , dimension(:,:),allocatable,save :: uorb 00058 real*8 , dimension(:,:) ,allocatable,save :: sinh2kh 00059 real*8 , dimension(:,:) ,allocatable,save :: hhwlocal 00060 real*8 , dimension(:,:,:),allocatable,save :: xadvec,yadvec,thetaadvec,dd,drr,dder 00061 real*8 , dimension(:,:,:),allocatable,save :: xradvec,yradvec,thetaradvec 00062 real*8 , dimension(:,:,:),allocatable,save :: ee_local 00063 real*8 , dimension(:),allocatable,save :: Hprev,thetaprev,gammafac_i,RH 00064 real*8 :: Herr,thetaerr,thetaerr_cyc,dtw 00065 real*8 :: dtheta_local 00066 logical :: stopiterate 00067 ! 00068 ! set dimension sizes 00069 select case (callType) 00070 case (callTypeStationary) 00071 ntheta_local = s%ntheta 00072 case (callTypeDirections) 00073 ntheta_local = s%ntheta_s 00074 end select 00075 ! 00076 ! Allocate 00077 if (.not. allocated(xadvec)) then 00078 allocate(xadvec (s%nx+1,s%ny+1,ntheta_local)) 00079 allocate(yadvec (s%nx+1,s%ny+1,ntheta_local)) 00080 allocate(thetaadvec(s%nx+1,s%ny+1,ntheta_local)) 00081 allocate(dd (s%nx+1,s%ny+1,ntheta_local)) 00082 allocate(dder (s%nx+1,s%ny+1,ntheta_local)) 00083 allocate(ee_local (s%nx+1,s%ny+1,ntheta_local)) 00084 allocate(dhdx(s%nx+1,s%ny+1)) 00085 allocate(dhdy(s%nx+1,s%ny+1)) 00086 allocate(dudx(s%nx+1,s%ny+1)) 00087 allocate(dudy(s%nx+1,s%ny+1)) 00088 allocate(dvdx(s%nx+1,s%ny+1)) 00089 allocate(dvdy(s%nx+1,s%ny+1)) 00090 allocate(uorb(s%nx+1,s%ny+1)) 00091 allocate(sinh2kh(s%nx+1,s%ny+1)) 00092 allocate(hhwlocal(s%nx+1,s%ny+1)) 00093 allocate(gammafac_i(s%ny+1)) 00094 allocate(RH(s%ny+1)) 00095 allocate(Hprev(s%ny+1)) 00096 allocate(thetaprev(s%ny+1)) 00097 ! 00098 if(par%scheme==SCHEME_WARMBEAM) then 00099 scheme_local = SCHEME_UPWIND_2 ! note, this is already stated as warning in log file during read of params.txt 00100 else 00101 scheme_local = par%scheme 00102 endif 00103 if(scheme_local .ne. SCHEME_UPWIND_1) then 00104 scheme_local_yadvec = SCHEME_UPWIND_1 00105 call writelog('lws','(a)', 'Warning: y-advection in stationary wave solver set to upwind_1 for convergence') 00106 else 00107 scheme_local_yadvec = scheme_local 00108 endif 00109 endif 00110 ! 00111 ! Allocate additional variables for stationary wave computation 00112 if ((.not. allocated(xradvec)) .and. (callType==callTypeStationary)) then 00113 allocate(xradvec(s%nx+1,s%ny+1,ntheta_local)) 00114 allocate(yradvec(s%nx+1,s%ny+1,ntheta_local)) 00115 allocate(thetaradvec(s%nx+1,s%ny+1,ntheta_local)) 00116 allocate(drr (s%nx+1,s%ny+1,ntheta_local)) 00117 endif 00118 ! 00119 ! Initialize 00120 xadvec = 0.0d0 00121 yadvec = 0.0d0 00122 thetaadvec = 0.0d0 00123 dd = 0.0d0 00124 dder = 0.0d0 00125 dhdx = 0.0d0 00126 dhdy = 0.0d0 00127 dudx = 0.0d0 00128 dudy = 0.0d0 00129 dvdx = 0.0d0 00130 dvdy = 0.0d0 00131 sinh2kh = 0.0d0 00132 uorb = 0.0d0 00133 ! 00134 if (callType==callTypeStationary) then 00135 xradvec = 0.0d0 00136 yradvec = 0.0d0 00137 thetaradvec = 0.0d0 00138 drr = 0.0d0 00139 endif 00140 ! 00141 ! Set switch for pointer variables (not strictly defined as Fortran pointers) 00142 select case (callType) 00143 case (callTypeStationary) 00144 hhwlocal = s%hhw 00145 ee_local = s%ee 00146 dtheta_local = s%dtheta 00147 case (callTypeDirections) 00148 hhwlocal = s%hhws 00149 ee_local = s%ee_s 00150 dtheta_local = s%dtheta_s 00151 end select 00152 ! 00153 ! Slopes of water depth 00154 call slope2D(hhwlocal,s%nx,s%ny,s%dsu,s%dnv,dhdx,dhdy,s%wete) 00155 ! 00156 ! Dano: limit slopes used in refraction to avoid unrealistic refraction speeds 00157 dhdx=sign(1.d0,dhdx)*min(abs(dhdx),0.1d0) 00158 dhdy=sign(1.d0,dhdy)*min(abs(dhdy),0.1d0) 00159 ! 00160 ! slopes of flow (in case of WCI) 00161 if (par%wci==1) then 00162 select case (callType) 00163 case(callTypeStationary) 00164 call slope2D(s%u,s%nx,s%ny,s%dsu,s%dnv,dudx,dudy,s%wete) 00165 call slope2D(s%v,s%nx,s%ny,s%dsu,s%dnv,dvdx,dvdy,s%wete) 00166 case (callTypeDirections) 00167 call slope2D(s%uws,s%nx,s%ny,s%dsu,s%dnv,dudx,dudy,s%wete) 00168 call slope2D(s%vws,s%nx,s%ny,s%dsu,s%dnv,dvdx,dvdy,s%wete) 00169 end select 00170 else 00171 dudx = 0.d0 00172 dudy = 0.d0 00173 dvdx = 0.d0 00174 dvdy = 0.d0 00175 endif 00176 ! wwvv these slope routines are in wave_timestep, and are 00177 ! MPI-aware 00178 ! 00179 ! Calculate once sinh(2kh) 00180 where(s%wete==1 .and. 2*hhwlocal*s%k<=3000.d0) 00181 sinh2kh=sinh(min(2*s%k*hhwlocal,10.0d0)) 00182 elsewhere 00183 sinh2kh = 3000.d0 00184 endwhere 00185 ! 00186 ! all dry cells have zero energy 00187 do itheta=1,ntheta_local 00188 where(s%wete==0) 00189 ee_local(:,:,itheta) = 0.d0 00190 endwhere 00191 enddo 00192 where(s%wete==0) 00193 s%E=0.d0 00194 s%H=0.d0 00195 endwhere 00196 ! 00197 ! wave directions 00198 select case (callType) 00199 case(callTypeStationary) 00200 if (par%snells==0) then 00201 forall (i=1:s%nx+1,j=1:s%ny+1,s%wete(i,j)==1) 00202 s%thetamean(i,j)=(sum(ee_local(i,j,:)*s%thet(i,j,:))/ntheta_local) / & 00203 (max(sum(ee_local(i,j,:)),0.00001d0)/ntheta_local) 00204 endforall 00205 else 00206 s%thetamean=asin(sin(s%theta0-s%alfaz(1,1))*s%c/s%c(1,1))+s%alfaz(1,1) 00207 s%costh(:,:,1)=cos(s%thetamean-s%alfaz) 00208 s%sinth(:,:,1)=sin(s%thetamean-s%alfaz) 00209 endif 00210 case(callTypeDirections) 00211 forall (i=1:s%nx+1,j=1:s%ny+1,s%wete(i,j)==1) 00212 s%thetamean(i,j)=(sum(ee_local(i,j,:)*s%thet_s(i,j,:))/ntheta_local) / & 00213 (max(sum(ee_local(i,j,:)),0.00001d0)/ntheta_local) 00214 endforall 00215 end select 00216 ! 00217 ! split wave velocities in wave grid directions theta 00218 select case (callType) 00219 case(callTypeStationary) 00220 call compute_wave_direction_velocities(s,par,0,dhdx,dhdy,dudx,dudy,dvdx,dvdy,sinh2kh) 00221 case(callTypeDirections) 00222 call compute_wave_direction_velocities(s,par,2,dhdx,dhdy,dudx,dudy,dvdx,dvdy,sinh2kh) 00223 end select 00224 ! 00225 ! Initialize at the boundary 00226 s%E(1,:)=max(sum(ee_local(1,:,:),2)*dtheta_local,0.d0) 00227 s%H(1,:)=sqrt(s%E(1,:)/par%rhog8) 00228 if (callType==callTypeStationary) s%R(1,:)=max(sum(s%rr(1,:,:),2)*dtheta_local,0.0d0) 00229 ! 00230 ! 00231 ! Initialize loop over grid 00232 ! 00233 ! write to screen that waves are updated 00234 if(xmaster) then 00235 select case (callType) 00236 case(callTypeStationary) 00237 call writelog('ls','(a,f0.2,a)','Computing wave transformation at t = ',par%t,' s') 00238 case(callTypeDirections) 00239 call writelog('ls','(a,f0.2,a)','Computing wave directions at t = ',par%t,' s') 00240 end select 00241 endif 00242 call progress_indicator(.true.,0.d0,5.d0,2.d0) 00243 imax=s%nx 00244 itermax = 0 00245 ! 00246 ! 00247 ! Start of loop of the grid 00248 do i=2,imax 00249 call progress_indicator(.false.,dble(i)/imax*100,5.d0,2.d0) 00250 ! 00251 ! determine internal time step 00252 select case (callType) 00253 case(callTypeStationary) 00254 dtw= .5d0*minval(s%dsu(i-1:i+1,jmin_ee:jmax_ee))/max(1.0d-6,maxval(abs(s%cgx(i-1:i+1,jmin_ee:jmax_ee,:)))) 00255 dtw=min(dtw,.5d0*minval(s%dnv(i,jmin_ee:jmax_ee)) /max(1.0d-6,maxval(abs(s%cgy(i,jmin_ee:jmax_ee,:) )))) 00256 dtw=min(dtw,.5d0*dtheta_local /max(1.0d-6,maxval(abs(s%ctheta(i,jmin_ee:jmax_ee,:) )))) 00257 case(callTypeDirections) 00258 dtw= .5d0*minval(s%dsu(i-1:i+1,jmin_ee:jmax_ee))/max(1.0d-6,maxval(abs(s%cgx_s(i-1:i+1,jmin_ee:jmax_ee,:)))) 00259 dtw=min(dtw,.5d0*minval(s%dnv(i,jmin_ee:jmax_ee)) /max(1.0d-6,maxval(abs(s%cgy_s(i,jmin_ee:jmax_ee,:) )))) 00260 dtw=min(dtw,.5d0*dtheta_local /max(1.0d-6,maxval(abs(s%ctheta_s(i,jmin_ee:jmax_ee,:) )))) 00261 end select 00262 ! 00263 !Dano: need to make sure all processes use the same dtw, min of all processes 00264 #ifdef USEMPI 00265 call xmpi_allreduce(dtw,MPI_MIN) 00266 #endif 00267 ! 00268 ! Reduced internal time step in case of WCI 00269 if(par%wci==1) then 00270 dtw = min(dtw,par%dt) 00271 endif 00272 ! 00273 ! Initialize iteration loop per gridline 00274 Herr=huge(1.d0) 00275 thetaerr = 2*par%px 00276 iter=0 00277 stopiterate=.false. 00278 ! 00279 ! Start of iteration loop per gridline 00280 do while (stopiterate .eqv. .false.) 00281 iter=iter+1 00282 Hprev=s%H(i,:) 00283 thetaprev = s%thetamean(i,:) 00284 ! 00285 ! transform energy to wave action 00286 i1=max(i-2,1) 00287 do itheta=1,ntheta_local 00288 where(s%wete(i1:i+1,:)==1) 00289 ee_local(i1:i+1,:,itheta) = ee_local(i1:i+1,:,itheta)/s%sigm(i1:i+1,:) 00290 endwhere 00291 enddo 00292 ! 00293 ! Upwind Euler timestep propagation 00294 ! 00295 ! M-Direction 00296 select case (callType) 00297 case(callTypeStationary) 00298 if (i==2) then 00299 call advecxho(ee_local(i-1:i+1,:,:),s%cgx(i-1:i+1,:,:),xadvec(i-1:i+1,:,:), & 00300 2,s%ny,ntheta_local,s%dnu(i-1:i+1,:),s%dsu(i-1:i+1,:),s%dsdnzi(i-1:i+1,:),SCHEME_UPWIND_1, & 00301 s%wete(i-1:i+1,:),dtw,s%dsz) 00302 else 00303 ! note: at the moment Warm-Beam is currently not a valid combination (automatic change to upwind_2 in params.F90) 00304 call advecxho(ee_local(i-2:i+1,:,:),s%cgx(i-2:i+1,:,:),xadvec(i-2:i+1,:,:), & 00305 3,s%ny,ntheta_local,s%dnu(i-2:i+1,:),s%dsu(i-2:i+1,:),s%dsdnzi(i-2:i+1,:),scheme_local, & 00306 s%wete(i-2:i+1,:),dtw,s%dsz) 00307 endif 00308 case(callTypeDirections) 00309 if (i==2) then 00310 call advecxho(ee_local(i-1:i+1,:,:),s%cgx_s(i-1:i+1,:,:),xadvec(i-1:i+1,:,:), & 00311 2,s%ny,ntheta_local,s%dnu(i-1:i+1,:),s%dsu(i-1:i+1,:),s%dsdnzi(i-1:i+1,:),SCHEME_UPWIND_1, & 00312 s%wete(i-1:i+1,:),dtw,s%dsz) 00313 else 00314 ! note: at the moment Warm-Beam is currently not a valid combination (automatic change to upwind_2 in params.F90) 00315 call advecxho(ee_local(i-2:i+1,:,:),s%cgx_s(i-2:i+1,:,:),xadvec(i-2:i+1,:,:), & 00316 3,s%ny,ntheta_local,s%dnu(i-2:i+1,:),s%dsu(i-2:i+1,:),s%dsdnzi(i-2:i+1,:),scheme_local, & 00317 s%wete(i-2:i+1,:),dtw,s%dsz) 00318 endif 00319 end select 00320 ! 00321 ! N-Direction 00322 if (s%ny>0) then 00323 select case (callType) 00324 case(callTypeStationary) 00325 call advecyho(ee_local(i,:,:),s%cgy(i,:,:),yadvec(i,:,:), & 00326 0,s%ny,ntheta_local,s%dsv(i,:),s%dnv(i,:),s%dsdnzi(i,:),scheme_local_yadvec,s%wete(i,:),dtw,s%dnz) 00327 case(callTypeDirections) 00328 call advecyho(ee_local(i,:,:),s%cgy_s(i,:,:),yadvec(i,:,:), & 00329 0,s%ny,ntheta_local,s%dsv(i,:),s%dnv(i,:),s%dsdnzi(i,:),scheme_local_yadvec,s%wete(i,:),dtw,s%dnz) 00330 end select 00331 endif 00332 ! 00333 ! Theta-Direction 00334 select case (callType) 00335 case(callTypeStationary) 00336 call advecthetaho(ee_local(i,:,:),s%ctheta(i,:,:),thetaadvec(i,:,:),0,s%ny,ntheta_local, & 00337 dtheta_local,scheme_local,s%wete(i,:)) 00338 case(callTypeDirections) 00339 call advecthetaho(ee_local(i,:,:),s%ctheta_s(i,:,:),thetaadvec(i,:,:),0,s%ny,ntheta_local, & 00340 dtheta_local,scheme_local,s%wete(i,:)) 00341 end select 00342 ! 00343 ! update wave action 00344 ee_local(i,:,:)=ee_local(i,:,:)-dtw*(xadvec(i,:,:) + yadvec(i,:,:) + thetaadvec(i,:,:)) 00345 ! 00346 ! transform back to wave energy 00347 do itheta=1,ntheta_local 00348 where(s%wete(i1:i+1,:)==1) 00349 ee_local(i1:i+1,:,itheta) = ee_local(i1:i+1,:,itheta)*s%sigm(i1:i+1,:) 00350 ee_local(i1:i+1,:,itheta)=max(ee_local(i1:i+1,:,itheta),0.0d0) 00351 endwhere 00352 enddo 00353 #ifdef USEMPI 00354 call xmpi_shift(ee_local(i-1:i+1,:,:),SHIFT_Y_R,1,2) 00355 call xmpi_shift(ee_local(i-1:i+1,:,:),SHIFT_Y_L,3,4) 00356 #endif 00357 ! 00358 ! Energy integrated over wave directions,Hrms 00359 where(s%wete(i,:)==1) 00360 s%E(i,:)=sum(ee_local(i,:,:),2)*dtheta_local 00361 s%H(i,:)=sqrt(s%E(i,:)/par%rhog8) 00362 endwhere 00363 ! 00364 ! adjust wave energy and height for gammax 00365 gammafac_i = (par%gammax*hhwlocal(i,:))/s%H(i,:) ! inverse of gammafac = s%H(i,:)/(par%gammax*hhwlocal(i,:)) 00366 do j=1,s%ny+1 00367 if (s%wete(i,j)==1 .and. gammafac_i(j)<1.d0) then 00368 do itheta=1,ntheta_local 00369 ee_local(i,j,itheta)=ee_local(i,j,itheta)*gammafac_i(j)**2 00370 enddo 00371 s%H(i,j)=s%H(i,j)*gammafac_i(j) 00372 s%E(i,j)=s%E(i,j)*gammafac_i(j)**2 00373 endif 00374 enddo 00375 ! 00376 ! redo wave directions (Dano: not for Snellius; Robert: also always for callTypeDirections) 00377 select case (callType) 00378 case(callTypeStationary) 00379 if (par%snells==0) then 00380 where(s%wete(i,:)==1) 00381 s%thetamean(i,:) = (sum(ee_local(i,:,:)*s%thet(i,:,:),2)/ntheta_local)/ & 00382 (max(sum(ee_local(i,:,:),2),0.000010d0)/ntheta_local) 00383 endwhere 00384 endif 00385 case(callTypeDirections) 00386 where(s%wete(i,:)==1) 00387 s%thetamean(i,:) = (sum(ee_local(i,:,:)*s%thet_s(i,:,:),2)/ntheta_local)/ & 00388 (max(sum(ee_local(i,:,:),2),0.000010d0)/ntheta_local) 00389 endwhere 00390 end select 00391 ! 00392 ! 00393 ! Compute wave dissipation 00394 ! 00395 ! Dissipation by breaking 00396 select case(par%break) 00397 case(BREAK_ROELVINK1,BREAK_ROELVINK2) 00398 call roelvink (par,s,i) 00399 case(BREAK_BALDOCK) 00400 call baldock (par,s,i) 00401 case(BREAK_JANSSEN) 00402 call janssen_battjes(par,s,i) 00403 end select 00404 ! 00405 ! Dissipation by bed friction 00406 where(s%fw(i,:)>0.d0 .and. s%wete(i,:)==1 .and. hhwlocal(i,:)<=par%fwcutoff) 00407 uorb(i,:)=par%px*s%H(i,:)/par%Trep/sinh(min(max(s%k(i,:),0.01d0)*hhwlocal(i,:),10.0d0)) 00408 s%Df(i,:)=0.28d0*par%rho*s%fw(i,:)*uorb(i,:)**3 ! Robert: note in wave-instationary the coefficient is 2/(3pi)?? 00409 elsewhere 00410 s%Df(i,:) = 0.d0 00411 end where 00412 ! 00413 ! Dissipation by vegetation computed in vegetation module 00414 ! 00415 ! 00416 ! Distribution of dissipation over directions and frequencies 00417 do itheta=1,ntheta_local 00418 where(s%wete(i,:)==1) 00419 ! just dissipation due to breaking, used for roller energy balance (in callTypeStationary only) 00420 dder(i,:,itheta)=ee_local(i,:,itheta)*s%D(i,:)/max(s%E(i,:),0.00001d0) 00421 ! Then all short wave energy dissipation, including bed friction and vegetation, used to reduce wave height 00422 ! Robert: note Dveg needs update for callTypeDirections, because based on only instantaneous H 00423 dd(i,:,itheta)=dder(i,:,itheta) + ee_local(i,:,itheta)*(s%Df(i,:)+s%Dveg(i,:))/max(s%E(i,:),0.00001d0) 00424 elsewhere 00425 dder(i,:,itheta)=0.d0 00426 dd(i,:,itheta)=0.d0 00427 endwhere 00428 end do 00429 ! 00430 ! 00431 ! Calculate roller energy balance (only needed for callTypeStationary) 00432 if (callType==callTypeStationary .and. par%roller==1) then 00433 ! 00434 ! M-direction 00435 if (i==2) then 00436 call advecxho(s%rr(i-1:i+1,:,:),s%cx(i-1:i+1,:,:),xradvec(i-1:i+1,:,:), & 00437 2,s%ny,ntheta_local,s%dnu(i-1:i+1,:),s%dsu(i-1:i+1,:),s%dsdnzi(i-1:i+1,:),SCHEME_UPWIND_1, & 00438 s%wete(i-1:i+1,:),dtw,s%dsz) 00439 else 00440 ! note: at the moment Warm-Beam is currently not a valid combination (automatic change to upwind_2 in params.F90) 00441 call advecxho(s%rr(i-2:i+1,:,:),s%cx(i-2:i+1,:,:),xradvec(i-2:i+1,:,:), & 00442 3,s%ny,ntheta_local,s%dnu(i-2:i+1,:),s%dsu(i-2:i+1,:),s%dsdnzi(i-2:i+1,:),scheme_local, & 00443 s%wete(i-2:i+1,:),dtw,s%dsz) 00444 endif 00445 ! 00446 ! N-Direction 00447 if (s%ny>0) then 00448 call advecyho(s%rr(i,:,:),s%cy(i,:,:),yradvec(i,:,:), & 00449 0,s%ny,ntheta_local,s%dsv(i,:),s%dnv(i,:),s%dsdnzi(i,:),scheme_local_yadvec,s%wete(i,:),dtw,s%dnz) 00450 endif 00451 ! 00452 ! Theta-Direction 00453 call advecthetaho(s%rr(i,:,:),s%ctheta(i,:,:),thetaradvec(i,:,:), & 00454 0,s%ny,ntheta_local,dtheta_local,scheme_local,s%wete(i,:)) 00455 00456 s%rr(i,:,:)=s%rr(i,:,:)-dtw*(xradvec(i,:,:)+yradvec(i,:,:)+thetaradvec(i,:,:)) 00457 s%rr(i,:,:)=max(s%rr(i,:,:),0.0d0) 00458 #ifdef USEMPI 00459 call xmpi_shift(s%rr(i-1:i,:,:),SHIFT_Y_R,1,2) 00460 call xmpi_shift(s%rr(i-1:i,:,:),SHIFT_Y_L,3,4) 00461 #endif 00462 endif 00463 ! 00464 ! 00465 ! Compute energy source and sink function 00466 ! 00467 ! update internal timestep 00468 do j=jmin_ee,jmax_ee 00469 if (s%wete(i,j)==1) then 00470 do itheta=1,ntheta_local 00471 if(ee_local(i,j,itheta)>0.d0 .and. dd(i,j,itheta)>0.d0) then 00472 dtw=min(dtw,.5*ee_local(i,j,itheta)/dd(i,j,itheta)) 00473 endif 00474 enddo 00475 endif 00476 enddo 00477 ! Dano: need to make sure all processes use the same dtw, min of all processes 00478 #ifdef USEMPI 00479 call xmpi_allreduce(dtw,MPI_MIN) 00480 #endif 00481 ! 00482 ! Timestep update of source and sink 00483 do j=jmin_ee,jmax_ee 00484 if(s%wete(i,j)==1) then 00485 do itheta=1,ntheta_local 00486 ee_local(i,j,itheta)=ee_local(i,j,itheta)-dtw*dd(i,j,itheta) 00487 ee_local(i,j,itheta)=max(ee_local(i,j,itheta),0.0d0) 00488 if(callType==callTypeStationary) then 00489 if (par%roller==1) then !Christophe 00490 drr(i,j,itheta) = 2*par%g*par%beta*max(s%rr(i,j,itheta),0.0d0)/& 00491 sqrt(s%cx(i,j,itheta)**2 +s%cy(i,j,itheta)**2) 00492 s%rr(i,j,itheta) = s%rr(i,j,itheta)+dtw*dder(i,j,itheta)-dtw*drr(i,j,itheta) 00493 s%rr(i,j,itheta) = max(s%rr(i,j,itheta),0.0d0) 00494 else 00495 drr(i,j,itheta)= 0.0d0 00496 s%rr(i,j,itheta)= 0.0d0 00497 end if 00498 endif 00499 enddo 00500 else 00501 ee_local(i,j,:)=0.0d0 00502 if(callType==callTypeStationary) then 00503 s%rr(i,j,:)=0.0d0 00504 drr(i,j,:)=0.0d0 00505 endif 00506 endif 00507 enddo 00508 ! 00509 ! Lateral boundary conditions 00510 if (xmpi_isleft .and. s%ny>0) then 00511 do itheta=1,ntheta_local 00512 ee_local(i,1,itheta)=ee_local(i,2,itheta) 00513 if(callType==callTypeStationary) s%rr(i,1,itheta)=s%rr(i,2,itheta) 00514 enddo 00515 s%k(:,1)=s%k(:,2) 00516 s%sigm(:,1)=s%sigm(:,2) 00517 endif 00518 if (xmpi_isright .and. s%ny>0) then 00519 do itheta=1,ntheta_local 00520 ee_local(i,s%ny+1,itheta)=ee_local(i,s%ny,itheta) 00521 if(callType==callTypeStationary) s%rr(i,s%ny+1,itheta)=s%rr(i,s%ny,itheta) 00522 end do 00523 s%k(:,s%ny+1)=s%k(:,s%ny) 00524 s%sigm(:,s%ny+1)=s%sigm(:,s%ny) 00525 endif 00526 ! 00527 ! 00528 ! Redo wave directions (Dano: not for Snellius; Robert: also always for callTypeDirections) 00529 select case (callType) 00530 case(callTypeStationary) 00531 if (par%snells==0) then 00532 where(s%wete(i,:)==1) 00533 s%thetamean(i,:) = (sum(ee_local(i,:,:)*s%thet(i,:,:),2)/ntheta_local)/ & 00534 (max(sum(ee_local(i,:,:),2),0.000010d0)/ntheta_local) 00535 endwhere 00536 endif 00537 case(callTypeDirections) 00538 where(s%wete(i,:)==1) 00539 s%thetamean(i,:) = (sum(ee_local(i,:,:)*s%thet_s(i,:,:),2)/ntheta_local)/ & 00540 (max(sum(ee_local(i,:,:),2),0.000010d0)/ntheta_local) 00541 endwhere 00542 end select 00543 ! 00544 ! forward-copy wave directions on dry cells in case they flood before the next wave update 00545 where(s%wete(i,:)==0) 00546 s%thetamean(i,:) = s%thetamean(i-1,:) 00547 endwhere 00548 ! 00549 ! 00550 ! Energy integrated over wave directions,Hrms 00551 where(s%wete(i,:)==1) 00552 s%E(i,:)=sum(ee_local(i,:,:),2)*dtheta_local 00553 s%H(i,:)=sqrt(s%E(i,:)/par%rhog8) 00554 elsewhere 00555 s%E(i,:)=0.d0 00556 s%H(i,:)=0.d0 00557 endwhere 00558 ! 00559 ! Roller energy 00560 if (callType==callTypeStationary) then 00561 where(s%wete(i,:)==1) 00562 s%R(i,:)=sum(s%rr(i,:,:),2)*dtheta_local 00563 s%DR(i,:)=sum(drr(i,:,:),2)*dtheta_local 00564 elsewhere 00565 s%R(i,:)=0.d0 00566 s%DR(i,:)=0.d0 00567 endwhere 00568 endif 00569 ! 00570 ! Correct roller for gammax 00571 ! adjust wave energy and height for gammax 00572 if(callType==callTypeStationary .and. par%rollergammax==1) then 00573 RH = sqrt(s%R(i,:)/par%rhog8) 00574 gammafac_i = (par%gammax*hhwlocal(i,:))/RH ! inverse of gammafac = s%H(i,:)/(par%gammax*hhwlocal(i,:)) 00575 do j=1,s%ny+1 00576 if (s%wete(i,j)==1 .and. gammafac_i(j)<1.d0) then 00577 do itheta=1,ntheta_local 00578 s%rr(i,j,itheta)=s%rr(i,j,itheta)*gammafac_i(j)**2 00579 enddo 00580 s%R(i,j)=RH(j)*gammafac_i(j) 00581 endif 00582 enddo 00583 endif 00584 ! 00585 ! 00586 ! Wave height and direction difference with last iteration 00587 Herr=maxval(abs(Hprev(jmin_ee:jmax_ee)-s%H(i,jmin_ee:jmax_ee)),mask=s%wete(i,jmin_ee:jmax_ee)==1) 00588 thetaerr = 0.d0 00589 do j=jmin_ee,jmax_ee 00590 thetaerr_cyc = minval( (/ abs(thetaprev(j)-(s%thetamean(i,j)-2*par%px)) , & 00591 abs(thetaprev(j)-(s%thetamean(i,j) )) , & 00592 abs(thetaprev(j)-(s%thetamean(i,j)+2*par%px)) /) ) 00593 thetaerr = max(thetaerr,thetaerr_cyc) 00594 enddo 00595 ! 00596 ! communicate error across MPI domains 00597 #ifdef USEMPI 00598 call xmpi_allreduce(Herr,MPI_MAX) 00599 call xmpi_allreduce(thetaerr,MPI_MAX) 00600 #endif 00601 ! 00602 ! 00603 ! Stopping criteria 00604 if (iter<par%maxiter) then 00605 if (Herr<par%maxerror .and. thetaerr<par%maxerror_angle) then 00606 stopiterate=.true. 00607 endif 00608 else 00609 stopiterate=.true. 00610 if(xmaster) then 00611 if (Herr>=par%maxerror) then 00612 call writelog('lsw','(a,i4,a,i4,a,f5.4)','Wave propagation row ',i,', iteration ',iter,', H error: ',Herr) 00613 endif 00614 if (thetaerr>=par%maxerror_angle) then 00615 call writelog('lsw','(a,i4,a,i4,a,f5.4)','Wave propagation row ',i,', iteration ', & 00616 iter,', dir error: ',thetaerr/par%px*180) 00617 endif 00618 endif 00619 endif 00620 ! 00621 enddo ! end interation loop per gridline 00622 ! 00623 ! Store maximum iterations update 00624 itermax = max(itermax,iter) 00625 enddo ! end loop over grid 2,nx 00626 ! 00627 ! 00628 ! write summary to log 00629 call writelog('ls','(a,i4)','Maximum number of iterations: ',itermax) 00630 ! 00631 ! 00632 ! store local energy "pointer" variable to s structure 00633 select case (callType) 00634 case(callTypeStationary) 00635 s%ee= ee_local 00636 case(callTypeDirections) 00637 s%ee_s = ee_local 00638 end select 00639 ! 00640 ! 00641 ! Boundary conditions at nx+1 00642 s%E(s%nx+1,:) = s%E(s%nx,:) 00643 s%H(s%nx+1,:) = s%H(s%nx,:) 00644 s%k(s%nx+1,:) = s%k(s%nx,:) 00645 s%sigm(s%nx+1,:) = s%sigm(s%nx,:) 00646 s%cg(s%nx+1,:) = s%cg(s%nx,:) 00647 s%c(s%nx+1,:) = s%c(s%nx,:) 00648 select case (callType) 00649 case(callTypeStationary) 00650 s%ee(s%nx+1,:,:) = s%ee(s%nx,:,:) 00651 s%rr(s%nx+1,:,:) = s%rr(s%nx,:,:) 00652 s%R(s%nx+1,:) = s%R(s%nx,:) 00653 s%DR(s%nx+1,:) = s%DR(s%nx,:) 00654 s%thet(s%nx+1,:,:) = s%thet(s%nx,:,:) 00655 case(callTypeDirections) 00656 s%ee_s(s%nx+1,:,:) = s%ee_s(s%nx,:,:) 00657 s%thet_s(s%nx+1,:,:) = s%thet_s(s%nx,:,:) 00658 end select 00659 ! 00660 ! 00661 ! Compute radiation stress and forcing terms (callType=callTypeStationary only) 00662 if (callType==callTypeStationary) then 00663 ! 00664 ! wave forces 00665 call compute_wave_forces(s) 00666 ! 00667 ! orbital velocity 00668 s%urms=uorb/sqrt(2.d0) 00669 ! 00670 ! Stokes drift and orbital velocities 00671 call compute_stokes_drift(s,par) 00672 endif 00673 ! 00674 end subroutine wave_stationary_directions 00675 end module wave_stationary_directions_module