XBeach
|
00001 module timestep_module 00002 00003 00004 ! Time steps in XBeach 00005 ! 00006 ! Relevant time variables 00007 ! 00008 ! [Main time loop] 00009 ! tstop: stop time simulation (set in params, used in boundaryconditions groundwater output params readtide readwind timestep varoutput waveparams xbeach) 00010 ! 00011 ! [Output] 00012 ! tint: time interval output global values (set in params, used in nonhydrostatic output params timestep timestep_old, varoutput) 00013 ! 00014 ! tintg: time interval output global values (set in params, used in params timestep) 00015 ! tintm: time interval output mean global values (set in params timestep varoutput, used in params timestep varianceupdate varoutput) 00016 ! tintp: time interval output point values (set in params, used in drifters params timestep) 00017 ! 00018 ! tsglobal: file with list of output times for global values (set in timestep, used in timestep) 00019 ! tsmean: file with list of output times for meanglobal values (set in timestep, used in timestep) 00020 ! tspoints: file with list of output times for point values (set in timestep, used in timestep) 00021 ! 00022 ! tnext: (set in params timestep timestep_old varoutput, used in params timestep timestep_old varoutput) 00023 ! 00024 ! [Hydrodynamic] 00025 ! tstart: start time of simulation (or output?!) (set in params, used in nonhydrostatic output params timestep) 00026 ! CFL: maximum courant number (set in params, used in params timestep timestep_old) 00027 ! 00028 ! [Boundary condition] 00029 ! rt: the record length of the boundary condition (set in params, waveparams, used in boundaryconditions params timestep waveparams) 00030 ! dtbc: boundary condition file time step dtbc (set in params, waveparams, used in params timestep waveparams) 00031 ! taper: time to spin up wave boundary conditions (set in params, used in nonhydrostatic output params timestep timestep_old varoutput) 00032 ! 00033 ! [Morphology] 00034 ! morfac: (set in params, used in boundaryconditions morphevolution params readtide readwind timestep varoutput waveparams) 00035 ! morstart: (set in params, used in morphevolution params timestep) 00036 ! 00037 ! [Waves] 00038 ! wavint: interval between stationary wave module calls (set in params, used in params timestep xbeach) 00039 ! 00040 ! [Tides] 00041 ! tidelen: length of tidal record (set in params readtide, used in boundaryconditions params readtide timestep) 00042 ! tideloc: number of input tidal time series (set in boundaryconditions groundwater params, used in boundaryconditions groundwater initialize params readtide timestep) 00043 ! 00044 ! Relevant Time functions and subroutines 00045 ! outputtimes_update 00046 ! 00047 ! XBeach time loop 00048 ! 0 tstop[s] 00049 ! |------------------------------------------------------------------------------------------| 00050 ! 00051 ! Hydrodynamic time scale flow_timestep(input: par%dt, output:s%hh) 00052 ! |--------------------|------------------|------------------|---------------|--------|------| 00053 ! The hydrodynamic timeloop computes at varying intervals. 00054 ! The interval (input:s%hh, par%CFL, par%dt, par%xz, s%nx, s%xz, s%nx, output=par%dt) is computed 00055 ! in timestep module 00056 ! 00057 ! The morphodynamic time scale(input: par%dt, par%morstart, p%morfac) 00058 ! |--------|------------------|------------------|---------------|--------|------| 00059 ! This scale can start at a different point in time (morstart) and uses a multiplication factor 00060 ! (morfac [s/s] (>=1)). 00061 ! 00062 ! Wave time scale 00063 ! |----------------|----------------|----------------|----------------|----------------|-----| 00064 ! At different time scales using wavint. 00065 ! Wave dispersion 00066 ! | 00067 ! Only calculated if par%t == par%dt 00068 ! 00069 ! Global output time scale fixed interval (tintg) 00070 ! |---------------------------|---------------------------|---------------------------|------- 00071 ! 00072 ! Mean output time scale fixed interval (tintm) 00073 ! |------------------------|------------------------|------------------------|---------------- 00074 ! 00075 ! Point out time scale fixed inteval(tintp) 00076 ! |---------------------------------|---------------------------------|------------------------ 00077 ! 00078 ! Global output time scale varying interval (tsglobal) 00079 ! |--------------------|-----------|---------------|-|-|------------|-------------|------------- 00080 ! 00081 ! Global output time scale varying interval (tsmean) 00082 ! |-----------------|-----------|-----------|-|-|------------|-------------|-------------------- 00083 ! 00084 ! Global output time scale varying interval (tspoint) 00085 ! |-------------------------|-----------|---------------|-|-|------------|-------------|-------- 00086 ! 00087 ! Boundary condition length [s] (rt) 00088 ! |-------------|-------------|-------------|-------------|-------------|-------------|---------- 00089 00090 implicit none 00091 save 00092 00093 private 00094 public timepars, timestep_init, timestep, outputtimes_update, compute_dt 00095 ! This structure contains the time variables which are computed during the simulation. 00096 ! Parameters which can be configured by users should go in params structure. 00097 type timepars 00098 real*8,dimension(:),allocatable :: tpg ! global output times 00099 real*8,dimension(:),allocatable :: tpp ! point oputput times 00100 real*8,dimension(:),allocatable :: tpm ! time average output times 00101 real*8,dimension(:),allocatable :: tph ! hotstart file output times 00102 real*8,dimension(:),allocatable :: tpw ! wave computation times 00103 real*8 :: tnext = -123 ! next time point for output 00104 00105 integer :: itg ! global output index (1 based) 00106 integer :: itp ! point output index (1 based) 00107 integer :: itm ! time average output index (1 based) 00108 integer :: itw ! wave computation index (1 based) 00109 integer :: ith ! hotstart computation index (1 based) 00110 00111 logical :: outputg ! output global variables? 00112 logical :: outputp ! output point variables? 00113 logical :: outputm ! output time average variables? 00114 logical :: outputw ! stop for wave computation 00115 logical :: outputh ! stop for hotstart file output 00116 logical :: output ! output any variable 00117 end type timepars 00118 00119 00120 00121 contains 00122 00123 subroutine timestep_init(par, tpar) 00124 use params, only: parameters 00125 use xmpi_module 00126 use readkey_module 00127 use logging_module, only: report_file_read_error, writelog 00128 use paramsconst 00129 implicit none 00130 00131 type(parameters),intent(inout) :: par 00132 type(timepars),intent(inout) :: tpar 00133 00134 real*8 :: iir 00135 integer :: i,ii,ier 00136 !character(80) :: fname 00137 00138 #ifdef USEMPI 00139 logical, parameter :: toall = .true. 00140 logical, parameter :: tocomp = .false. 00141 #endif 00142 00143 ! initialize the time to 0 00144 par%t = 0.0d0 00145 00146 tpar%tnext = 0.0d0 00147 ! initialize timestep counters 00148 tpar%itg = 0 00149 tpar%itp = 0 00150 tpar%itm = 0 00151 tpar%itw = 0 00152 ! initialize output, default no output 00153 tpar%outputg = .FALSE. 00154 tpar%outputp = .FALSE. 00155 tpar%outputm = .FALSE. 00156 tpar%outputw = .FALSE. 00157 tpar%output = .FALSE. 00158 00159 00160 !!!!! OUTPUT TIME POINTS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 00161 ! If working in instat 0 or instat 40 we want time to coincide at wavint timesteps 00162 if (par%wavemodel==WAVEMODEL_STATIONARY .or. par%single_dir==1) then 00163 if(xmaster) then 00164 ii=ceiling(par%tstop/par%wavint) 00165 allocate(tpar%tpw(ii)) 00166 do i=1,ii 00167 tpar%tpw(i)=real(i)*par%wavint 00168 enddo 00169 endif 00170 #ifdef USEMPI 00171 call xmpi_bcast(ii,toall) 00172 if (.not.xmaster) then 00173 allocate(tpar%tpw(ii)) 00174 endif 00175 call xmpi_bcast(tpar%tpw,toall) 00176 #endif 00177 else 00178 allocate(tpar%tpw(0)) 00179 endif 00180 00181 ! If we want global output then 00182 if (par%nglobalvar/=0) then 00183 if(xmaster) then 00184 if (par%tsglobal/=' ') then 00185 open(10,file=par%tsglobal) 00186 read(10,*,iostat=ier)iir 00187 if (ier .ne. 0) then 00188 call report_file_read_error(par%tsglobal) 00189 endif 00190 ii = nint(iir) 00191 allocate(tpar%tpg(ii)) 00192 do i=1,ii 00193 read(10,*,iostat=ier)tpar%tpg(i) 00194 if (ier .ne. 0) then 00195 call report_file_read_error(par%tsglobal) 00196 endif 00197 enddo 00198 tpar%tpg=tpar%tpg/max(par%morfac,1.d0) 00199 close(10) 00200 else 00201 ii=floor((par%tstop-par%tstart)/par%tintg)+1 00202 allocate(tpar%tpg(ii)) 00203 do i=1,ii 00204 tpar%tpg(i)=par%tstart+par%tintg*real(i-1) 00205 enddo 00206 endif 00207 endif !xmaster 00208 #ifdef USEMPI 00209 call xmpi_bcast(ii,toall) 00210 if (.not.xmaster) then 00211 allocate(tpar%tpg(ii)) 00212 endif 00213 call xmpi_bcast(tpar%tpg,toall) 00214 #endif 00215 else 00216 allocate(tpar%tpg(0)) 00217 endif ! nglobalvar /=0 00218 00219 ! If we want point output then 00220 if ((par%npoints+par%nrugauge+par%ndrifter)>0) then 00221 if (xmaster) then 00222 if (par%tspoints/=' ') then 00223 open(10,file=par%tspoints) 00224 read(10,*,iostat=ier)iir 00225 if (ier .ne. 0) then 00226 call report_file_read_error(par%tspoints) 00227 endif 00228 ii = nint(iir) 00229 allocate(tpar%tpp(ii)) 00230 do i=1,ii 00231 read(10,*,iostat=ier)tpar%tpp(i) 00232 if (ier .ne. 0) then 00233 call report_file_read_error(par%tspoints) 00234 endif 00235 enddo 00236 tpar%tpp=tpar%tpp/max(par%morfac,1.d0) 00237 close(10) 00238 else 00239 ii=floor((par%tstop-par%tstart)/par%tintp)+1 00240 allocate(tpar%tpp(ii)) 00241 do i=1,ii 00242 tpar%tpp(i)=par%tstart+par%tintp*real(i-1) 00243 enddo 00244 endif 00245 endif ! xmaster 00246 #ifdef USEMPI 00247 call xmpi_bcast(ii,toall) 00248 if (.not.xmaster) then 00249 allocate(tpar%tpp(ii)) 00250 endif 00251 call xmpi_bcast(tpar%tpp,toall) 00252 #endif 00253 else 00254 allocate(tpar%tpp(0)) 00255 endif ! (npoints+nrugauge)>0 00256 00257 ! If we want time-average output then 00258 if (par%nmeanvar>0) then 00259 if(xmaster) then 00260 if (par%tsmean/=' ') then 00261 open(10,file=par%tsmean) 00262 read(10,*,iostat=ier)iir 00263 if (ier .ne. 0) then 00264 call report_file_read_error(par%tsmean) 00265 endif 00266 ii = nint(iir) 00267 allocate(tpar%tpm(ii)) 00268 do i=1,ii 00269 read(10,*,iostat=ier)tpar%tpm(i) 00270 if (ier .ne. 0) then 00271 call report_file_read_error(par%tsmean) 00272 endif 00273 enddo 00274 tpar%tpm=tpar%tpm/max(par%morfac,1.d0) 00275 close(10) 00276 else 00277 ii=floor((par%tstop-par%tstart)/par%tintm)+1 00278 if (ii<=1) then 00279 call writelog('lse','','Tintm is larger than output simulation time ') 00280 call halt_program 00281 endif 00282 allocate(tpar%tpm(ii)) 00283 do i=1,ii 00284 tpar%tpm(i)=par%tstart+par%tintm*real(i-1) 00285 enddo 00286 endif 00287 endif 00288 #ifdef USEMPI 00289 call xmpi_bcast(ii,toall) 00290 if (.not.xmaster) then 00291 allocate(tpar%tpm(ii)) 00292 endif 00293 call xmpi_bcast(tpar%tpm,toall) 00294 #endif 00295 else 00296 allocate(tpar%tpm(0)) 00297 00298 endif ! nmeanvar > 0 00299 00300 ! If we want hotstart output then 00301 if (par%writehotstart==1) then 00302 if(xmaster) then 00303 if (par%tshotstart/=' ') then 00304 open(10,file=par%tshotstart) 00305 read(10,*,iostat=ier)iir 00306 if (ier .ne. 0) then 00307 call report_file_read_error(par%tshotstart) 00308 endif 00309 ii = nint(iir) 00310 allocate(tpar%tph(ii)) 00311 do i=1,ii 00312 read(10,*,iostat=ier)tpar%tph(i) 00313 if (ier .ne. 0) then 00314 call report_file_read_error(par%tshotstart) 00315 endif 00316 enddo 00317 tpar%tph=tpar%tph/max(par%morfac,1.d0) 00318 close(10) 00319 else 00320 ii=floor(par%tstop/par%tinth) ! don't want hotstart at t=0 00321 if (ii<=0) then 00322 call writelog('lse','','Tinth is larger than output simulation time ') 00323 call halt_program 00324 endif 00325 allocate(tpar%tph(ii)) 00326 do i=1,ii 00327 tpar%tph(i)=par%tinth*real(i) ! don't start at t=0 00328 enddo 00329 endif 00330 endif 00331 #ifdef USEMPI 00332 call xmpi_bcast(ii,toall) 00333 if (.not.xmaster) then 00334 allocate(tpar%tph(ii)) 00335 endif 00336 call xmpi_bcast(tpar%tph,toall) 00337 #endif 00338 else 00339 allocate(tpar%tph(0)) 00340 00341 endif ! wrtitehotstart == 1 00342 00343 end subroutine timestep_init 00344 00345 00346 subroutine outputtimes_update(par, tpar) 00347 use params, only: parameters 00348 use xmpi_module 00349 use logging_module, only: writelog 00350 implicit none 00351 type(parameters),intent(inout) :: par 00352 type(timepars), intent(inout) :: tpar 00353 real*8 :: t1,t2,t3,t4,t5 00354 00355 !if (tpar%outputm .or. tpar%itm .eq. 0) then 00356 ! par%tintm = tpar%tpm(min(tpar%itm+2,size(tpar%tpm)))-tpar%tpm(tpar%itm+1) 00357 ! par%tintm = max(par%tintm,tiny(0.d0)) 00358 !end if 00359 00360 ! Current timestep: 00361 ! check if we need output at the current timestep 00362 ! do we have anymore output time points, is it equal to the current? 00363 if (size(tpar%tpg) .gt. 0) then 00364 tpar%outputg = abs(tpar%tpg(min(tpar%itg+1,size(tpar%tpg)))-par%t) .le. 0.0000001d0 00365 ! if global output has last output before tstop, this minimum is necessary 00366 endif 00367 if (size(tpar%tpp) .gt. 0) then 00368 tpar%outputp = abs(tpar%tpp(min(tpar%itp+1,size(tpar%tpp)))-par%t) .le. 0.0000001d0 00369 endif 00370 if (size(tpar%tpm) .gt. 0) then 00371 tpar%outputm = abs(tpar%tpm(min(tpar%itm+1,size(tpar%tpm)))-par%t) .le. 0.0000001d0 00372 endif 00373 if (size(tpar%tpw) .gt. 0) then 00374 tpar%outputw = abs(tpar%tpw(min(tpar%itw+1,size(tpar%tpw)))-par%t) .le. 0.0000001d0 00375 endif 00376 if (size(tpar%tph) .gt. 0) then 00377 tpar%outputh = abs(tpar%tph(min(tpar%ith+1,size(tpar%tph)))-par%t) .le. 0.0000001d0 00378 endif 00379 00380 ! tpar%outputg = (size(tpar%tpg) .gt. tpar%itg) .and. (abs(tpar%tpg(tpar%itg+1)-par%t) .le. 0.0000001d0) 00381 ! tpar%outputp = (size(tpar%tpp) .gt. tpar%itp) .and. (abs(tpar%tpp(tpar%itp+1)-par%t) .le. 0.0000001d0) 00382 ! tpar%outputm = (size(tpar%tpm) .gt. tpar%itm) .and. (abs(tpar%tpm(tpar%itm+1)-par%t) .le. 0.0000001d0) 00383 ! tpar%outputc = (size(tpar%tpc) .gt. tpar%itc) .and. (abs(tpar%tpc(tpar%itc+1)-par%t) .le. 0.0000001d0) 00384 ! tpar%outputw = (size(tpar%tpw) .gt. tpar%itw) .and. (abs(tpar%tpw(tpar%itw+1)-par%t) .le. 0.0000001d0) 00385 tpar%output = (tpar%outputg .or. tpar%outputp .or. tpar%outputm .or. tpar%outputw .or. tpar%outputh) 00386 00387 ! if we are updating at the current timestep, increase the counter by 1 00388 ! 00389 ! update output counter 00390 if (tpar%outputg) tpar%itg = tpar%itg + 1 00391 if (tpar%outputp) tpar%itp = tpar%itp + 1 00392 if (tpar%outputm) tpar%itm = tpar%itm + 1 00393 if (tpar%outputw) tpar%itw = tpar%itw + 1 00394 if (tpar%outputh) tpar%ith = tpar%ith + 1 00395 00396 ! Next time step: 00397 ! calculate the output for the following time 00398 ! this routine computes the next timestep at which output should be generated 00399 ! Determine next time step 00400 t1=minval(tpar%tpg,MASK=tpar%tpg .gt. par%t+0.0000001d0) 00401 t2=minval(tpar%tpp,MASK=tpar%tpp .gt. par%t+0.0000001d0) 00402 t3=minval(tpar%tpm,MASK=tpar%tpm .gt. par%t+0.0000001d0) 00403 t4=minval(tpar%tpw,MASK=tpar%tpw .gt. par%t+0.0000001d0) 00404 t5=minval(tpar%tph,MASK=tpar%tph .gt. par%t+0.0000001d0) 00405 00406 tpar%tnext=min(t1,t2,t3,t4,t5,par%tstop) 00407 00408 if (tpar%tnext .eq. huge(tpar%tpg) .and. par%t .eq. 0) then 00409 call writelog('ls','', 'no output times found, setting tnext to tstop') 00410 tpar%tnext = par%tstop 00411 end if 00412 00413 end subroutine outputtimes_update 00414 00415 00416 subroutine compute_dt(s,par, tpar, it, ilim, jlim, dtref, dt, ierr, limtypeout) 00417 use params, only: parameters 00418 use spaceparams 00419 use xmpi_module 00420 use logging_module 00421 use paramsconst 00422 00423 IMPLICIT NONE 00424 00425 type(spacepars), intent(inout) :: s 00426 type(parameters), intent(inout) :: par 00427 type(timepars), intent(inout) :: tpar 00428 integer, intent(inout) :: it 00429 integer, intent(out), optional :: ierr,limtypeout 00430 real*8, intent(in), optional :: dt 00431 real*8, intent(inout) :: dtref 00432 integer, intent(inout) :: ilim, jlim 00433 integer :: i 00434 integer :: j,j1,j2 00435 integer :: n,limtype 00436 real*8 :: mdx,mdy,tny 00437 real*8,save :: dtold 00438 real*8 :: celeru 00439 00440 if(.not. xcompute) return 00441 00442 celeru = 0.d0 00443 limtype = 0 00444 00445 ! Super fast 1D 00446 if (s%ny==0) then 00447 j1 = 1 00448 else 00449 j1 = 2 00450 endif 00451 00452 ! Calculate dt based on the Courant number. 00453 ! Check when we need next output. 00454 ! Next time step will be, min(output times, t+dt) 00455 00456 if (present(ierr)) then 00457 ierr = 0 00458 endif 00459 tny = tiny(0.d0) 00460 00461 ! Robert new time step criterion 00462 if (par%t<=0.0d0 .and. par%hotstart==0) then ! conservative estimate in case of zeros initialization 00463 par%dt = par%CFL*min(minval(s%dsu(1:s%nx+1,1:s%ny+1)), & 00464 minval(s%dnv(1:s%nx+1,1:s%ny+1))) & 00465 /sqrt(maxval(s%hh)*par%g) 00466 dtref = 0.d0 00467 if (tpar%tnext > par%dt) then 00468 n = ceiling((tpar%tnext-par%t)/par%dt) 00469 par%dt = (tpar%tnext-par%t)/n 00470 end if 00471 elseif(par%t<=0.0d0 .and. par%hotstart==1) then ! conservative estimate in case of hotstart initialization 00472 par%dt = par%CFL*min(minval(s%dsu(1:s%nx+1,1:s%ny+1)), & 00473 minval(s%dnv(1:s%nx+1,1:s%ny+1))) & 00474 /maxval(sqrt(max(s%zs-s%zb,par%eps)*par%g)+sqrt(s%uu**2+s%vv**2)) 00475 dtref = 0.d0 00476 if (tpar%tnext > par%dt) then 00477 n = ceiling((tpar%tnext-par%t)/par%dt) 00478 par%dt = (tpar%tnext-par%t)/n 00479 end if 00480 else 00481 par%dt=huge(0.0d0) ! Seed dt 00482 dtold = par%dt 00483 limtype = 0 00484 if (s%ny>2) then 00485 do j=jmin_ee,jmax_ee 00486 do i=imin_ee,imax_ee 00487 if(s%wetu(i,j)==1) then 00488 ! u-points 00489 mdx=s%dsu(i+1,j) 00490 mdy=min(s%dnv(i,j),s%dnv(i,j-1)) 00491 ! x-component 00492 par%dt=min(par%dt,mdx/max(tny,max(sqrt(par%g*s%hu(i,j))+abs(s%uu(i,j)),abs(s%ueu(i,j))))) !Jaap: include sediment advection velocities 00493 ! y-component 00494 par%dt=min(par%dt,mdy/max(tny,(sqrt(par%g*s%hu(i,j))+abs(s%vu(i,j))))) 00495 if (par%dt<dtold) then 00496 ilim = i 00497 jlim = j 00498 limtype = 1 00499 dtold = par%dt 00500 endif 00501 endif 00502 if(s%wetv(i,j)==1) then 00503 ! v-points 00504 mdx=min(s%dsu(i,j),s%dsu(i-1,j)) 00505 mdy=s%dnv(i,j) 00506 ! x-component 00507 par%dt=min(par%dt,mdx/max(tny,(sqrt(par%g*s%hv(i,j))+abs(s%uv(i,j))))) 00508 ! y-component 00509 par%dt=min(par%dt,mdy/max(tny,max(sqrt(par%g*s%hv(i,j))+abs(s%vv(i,j)),abs(s%vev(i,j))))) !Jaap: include sediment advection velocities 00510 00511 if (par%dt<dtold) then 00512 ilim = i 00513 jlim = j 00514 limtype = 2 00515 dtold = par%dt 00516 endif 00517 endif 00518 if(s%wetz(i,j)==1) then 00519 mdx = min(s%dsu(i,j),s%dsz(i,j))**2 00520 mdy = min(s%dnv(i,j),s%dnz(i,j))**2 00521 00522 par%dt=min(par%dt,0.5d0*mdx*mdy/(mdx+mdy)/max(s%nuh(i,j),1e-6)) 00523 00524 if (par%dt<dtold) then 00525 ilim = i 00526 jlim = j 00527 limtype = 3 00528 dtold = par%dt 00529 endif 00530 00531 !Bas: the following criterion is not yet tested for 2D 00532 !par%dt=min(par%dt,0.5d0*mdx/max(s%Dc(i,j)*s%wetz(i,j),1e-6)) 00533 !par%dt=min(par%dt,0.5d0*mdy/max(s%Dc(i,j)*s%wetz(i,j),1e-6)) 00534 endif 00535 enddo 00536 enddo 00537 else 00538 j2=max(s%ny,1) ! Robert: hmmm, in sf1D this should be 1, in "old" 1d this should be 2 00539 do i=imin_ee,imax_ee 00540 if(s%wetu(i,j2)==1) then 00541 ! u-points 00542 mdx=s%dsu(i,j2) 00543 par%dt=min(par%dt,mdx/max(tny,max(sqrt(par%g*s%hu(i,j2))+abs(s%uu(i,j2)),abs(s%ueu(i,j2))))) !Jaap: include sediment advection velocities 00544 if (par%dt<dtold) then 00545 ilim = i 00546 jlim = j2 00547 limtype = 1 00548 dtold = par%dt 00549 endif 00550 ! u-points bed celerity ! Dano 00551 celeru=0.1d0*abs(sum(s%Subg(i,j2,:))+sum(s%Susg(i,j2,:)))*par%morfac/(1.d0-par%por) 00552 par%dt=min(par%dt,mdx/max(tny,celeru)) 00553 endif 00554 if(s%wetz(i,j2)==1) then 00555 ! v-points 00556 mdx=min(s%dsu(i,j2),s%dsu(i-1,j2)) 00557 par%dt=min(par%dt,mdx/max(tny,(sqrt(par%g*s%hv(i,j2))+abs(s%uv(i,j2))))) 00558 if (par%dt<dtold) then 00559 ilim = i 00560 jlim = j2 00561 limtype = 2 00562 dtold = par%dt 00563 endif 00564 00565 mdx = min(s%dsu(i,j2),s%dsz(i,j2))**2 00566 00567 if (par%dy > 0.d0) then 00568 mdy = par%dy 00569 else 00570 mdy = mdx 00571 endif 00572 00573 par%dt=min(par%dt,0.5d0*mdx*mdy/(mdx+mdy)/max(s%nuh(i,j2),1e-6)) 00574 if (par%dt<dtold) then 00575 ilim = i 00576 jlim = j2 00577 limtype = 3 00578 dtold = par%dt 00579 endif 00580 if (par%sedtrans==1 .and. par%facDc>0.d0) then 00581 par%dt=min(par%dt,0.5d0*mdx/max(s%Dc(i,j2),1e-6)) 00582 endif 00583 endif 00584 enddo 00585 endif 00586 00587 if (s%ny>0) then 00588 par%dt=par%dt*par%CFL*0.5d0 00589 else 00590 par%dt=par%dt*par%CFL*0.5d0 00591 endif 00592 00593 ! groundwater stability 00594 if (par%gwflow==1 .and. par%gwnonh==0) then 00595 j2=max(s%ny,1) 00596 do j=j1,j2 00597 do i=2,s%nx 00598 ! Vreugdenhil: 00599 ! 2*kx*gwheight*dt/dx2 < CFL -> dt = (CFL*dx2)/(2*kx*gwheight) 00600 ! par%dt=min(par%dt,par%CFL*s%dsc(i,j)**2/(2*par%kx*s%gwheight(i,j))) 00601 ! 00602 ! Wikipedia: http://en.wikipedia.org/wiki/Von_Neumann_stability_analysis for FTCS: 00603 ! 2*a*dt/dx2 < 1 , where dh/dt = a *d2h/dx2 -> a = k/por 00604 ! 2*k/por*dt/dx2 = CFL -> dt = CFL*dx2*por/2/k 00605 par%dt=min(par%dt,par%CFL*s%dsc(i,j)**2*par%por/(2*par%kx)) 00606 if (par%dt<dtold) then 00607 ilim = i 00608 jlim = j 00609 limtype = 4 00610 dtold = par%dt 00611 endif 00612 enddo 00613 enddo 00614 if (par%ny>2) then 00615 do j=j1,j2 00616 do i=2,s%nx 00617 ! 2*ky*gwheight*dt/dy2 < CFL -> dt = (CFL*dy2)/(2*ky*gwheight) 00618 ! par%dt=min(par%dt,par%CFL*s%dnc(i,j)**2/(2*par%ky*s%gwheight(i,j))) 00619 par%dt=min(par%dt,par%CFL*s%dnc(i,j)**2*par%por/(2*par%ky)) 00620 if (par%dt<dtold) then 00621 ilim = i 00622 jlim = j 00623 limtype = 4 00624 dtold = par%dt 00625 endif 00626 enddo 00627 enddo 00628 endif 00629 endif 00630 00631 if (par%swave==1) then 00632 #ifdef USEMPI 00633 ! Dano: no refraction if ntheta==1 so no need for this check 00634 if (s%ntheta>1) then 00635 par%dt=min(par%dt,par%CFL*s%dtheta/(maxval(maxval(abs(s%ctheta),3)*real(s%wetz))+tny)) 00636 endif 00637 #else 00638 ! if (par%instat(1:4)/='stat') then 00639 ! wwvv: hoping that this is a correct translation: 00640 select case (par%wavemodel) 00641 case(WAVEMODEL_STATIONARY) 00642 continue 00643 case default 00644 par%dt=min(par%dt,par%CFL*s%dtheta/(maxval(maxval(abs(s%ctheta),3)*real(s%wetz))+tny)) 00645 end select 00646 #endif 00647 endif 00648 !To avoid large timestep differences due to output, which can cause instabities 00649 !in the hanssen (leapfrog) scheme, we smooth the timestep. 00650 00651 if (tpar%tnext > par%t) then 00652 ! sometime dt too small and then integer overflow. Catch with check beforehand 00653 if ((tpar%tnext-par%t)/par%dt<dble(0.9*huge(0))) then 00654 n = ceiling((tpar%tnext-par%t)/par%dt) 00655 par%dt = (tpar%tnext-par%t)/n 00656 endif 00657 end if 00658 end if ! first, or other time step 00659 00660 if (dtref .eq. 0.0d0) then 00661 ! If dtref is not yet set. 00662 dtref = par%dt 00663 #ifdef USEMPI 00664 ! Use the same dtref everywhere. 00665 call xmpi_allreduce(dtref,MPI_MIN) 00666 #endif 00667 end if 00668 00669 ! wwvv: In the mpi version par%dt will be calculated different 00670 ! on different processes. So, we take the minimum of all dt's 00671 #ifdef USEMPI 00672 call xmpi_allreduce(par%dt,MPI_MIN) 00673 #endif 00674 00675 ! maximize dt with given dt 00676 if (present(dt)) then 00677 par%dt = min(dt, par%dt) 00678 end if 00679 00680 if (present(limtypeout)) then 00681 limtypeout = limtype 00682 endif 00683 00684 end subroutine compute_dt 00685 00686 subroutine timestep(s,par, tpar, it, dt, ierr) 00687 use params 00688 use spaceparams 00689 use xmpi_module 00690 use logging_module 00691 use paramsconst 00692 00693 IMPLICIT NONE 00694 00695 type(spacepars), intent(inout) :: s 00696 type(parameters), intent(inout) :: par 00697 type(timepars), intent(inout) :: tpar 00698 integer, intent(inout) :: it 00699 integer, intent(out), optional :: ierr 00700 real*8, intent(in), optional :: dt 00701 integer :: ilim 00702 integer :: jlim 00703 integer :: limtype 00704 real*8 :: fac 00705 real*8,save :: dtref 00706 00707 if(.not. xcompute) return 00708 00709 call compute_dt(s,par, tpar, it, ilim, jlim, dtref, dt=dt, ierr=ierr,limtypeout=limtype) 00710 00711 par%t=par%t+par%dt 00712 00713 if(par%t >= tpar%tnext) then 00714 par%dt = par%dt-(par%t-tpar%tnext) 00715 par%t = tpar%tnext 00716 it = it+1 00717 end if 00718 00719 ! Sometimes dtref is set incorrectly in intialization. We want to stop sudden changes 00720 ! in time step size, so allow dtref to change slowely to current situations. If simulation 00721 ! requires smaller timestep due to e.g. overwash, this should not stop the simulation. 00722 ! Errors occur in O(1-10) timesteps. Therefore filter on O(1000-10000) timesteps 00723 fac = 1.d0/5000 00724 dtref = (1.d0-fac)*dtref + fac*par%dt 00725 00726 if (((dtref/par%dt>par%maxdtfac .and. par%t<tpar%tnext) .or. par%dt/dtref>par%maxdtfac) & 00727 .and. par%defuse==1) then 00728 00729 call writelog('lswe','','Quit XBeach since computational time implodes/explodes') 00730 call writelog('lswe','','Please check output at the end of the simulation') 00731 select case (limtype) 00732 case (0) 00733 call writelog('lswe','(a)','Time constrain criterium exceeded in all cells') 00734 case (1) 00735 call writelog('lswe','(a,i0,a,i0,a)','U-velocities are too high in cell (',ilim,',',jlim,')(M,N)') 00736 case (2) 00737 call writelog('lswe','(a,i0,a,i0,a)','V-velocities are too high in cell (',ilim,',',jlim,')(M,N)') 00738 case (3) 00739 call writelog('lswe','(a,i0,a,i0,a)','Viscosity condition is too high in cell (',ilim,',',jlim,')(M,N)') 00740 case (4) 00741 call writelog('lswe','(a,i0,a,i0,a)','Groundwater condition is too high in cell (',ilim,',',jlim,')(M,N)') 00742 end select 00743 call writelog('lswe','','dtref: ',dtref) 00744 call writelog('lswe','','par%dt: ',par%dt) 00745 00746 ! Force output before exit in main time loop 00747 tpar%outputg = (size(tpar%tpg) .gt. 0) 00748 tpar%outputp = (size(tpar%tpp) .gt. 0) 00749 tpar%outputm = (size(tpar%tpm) .gt. 0) 00750 tpar%outputh = (size(tpar%tph) .gt. 0) 00751 ! set output time to current time 00752 if (tpar%outputg) tpar%tpg=min(tpar%tpg,par%t) 00753 if (tpar%outputp) tpar%tpp=min(tpar%tpp,par%t) 00754 if (tpar%outputm) tpar%tpm=min(tpar%tpm,par%t) 00755 if (tpar%outputh) tpar%tph=min(tpar%tph,par%t) 00756 tpar%output = (tpar%outputg .or. tpar%outputp .or. tpar%outputm .or. tpar%outputh) 00757 if (present(ierr)) then 00758 ierr = 1 00759 endif 00760 endif 00761 00762 end subroutine timestep 00763 end module timestep_module