83 :: pvar,cvar,ptmp,ctmp,cold, & !< prim/cons state vectors
84 src,geo_src, & !< source terms
85 rhs, & !< ODE right hand side
86 cerr,cerr_max, & !< error control & output
93 INTEGER :: dtcause,dtmincause
95 REAL,
POINTER :: dtmean, dtstddev
103 LOGICAL :: always_update_bccsound
110 INTEGER :: checkdatabm
111 REAL :: pmin,rhomin,tmin
116 REAL,
DIMENSION(:),
POINTER :: tol_abs
120 REAL,
DIMENSION(:,:,:,:),
POINTER :: phi,oldphi_s,&
122 REAL,
DIMENSION(:),
POINTER :: gamma
125 REAL,
DIMENSION(:,:,:,:),
POINTER :: xfluxdydz,yfluxdzdx,zfluxdxdy
126 REAL,
DIMENSION(:,:,:,:),
POINTER :: amax
127 REAL,
DIMENSION(:,:),
POINTER :: bflux
128 LOGICAL :: write_error
129 INTEGER,
DIMENSION(:,:),
POINTER :: shift=>null()
130 REAL,
DIMENSION(:,:),
POINTER :: buf=>null()
131 REAL,
DIMENSION(:,:),
POINTER :: w=>null()
132 REAL,
DIMENSION(:,:),
POINTER :: delxy =>null()
152 procedure(solveode),
DEFERRED :: solveode
158 SUBROUTINE solveode(this,Mesh,Physics,Sources,Fluxes,time,dt,err)
161 CLASS(timedisc_base),
INTENT(INOUT) :: this
162 CLASS(mesh_base),
INTENT(IN) :: Mesh
163 CLASS(physics_base),
INTENT(INOUT) :: Physics
164 CLASS(sources_base),
POINTER :: Sources
165 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
166 REAL,
INTENT(IN) :: time
167 REAL,
INTENT(INOUT) :: dt, err
173 CLASS(timedisc_base) :: this
198 "dynamic background velocity ", &
199 "user supplied fixed background velocity ", &
215 SUBROUTINE inittimedisc(this,Mesh,Physics,config,IO,ttype,tname)
223 CLASS(timedisc_base),
INTENT(INOUT) :: this
224 CLASS(mesh_base),
INTENT(INOUT) :: Mesh
225 CLASS(physics_base),
INTENT(IN) :: Physics
226 TYPE(Dict_TYP),
POINTER :: config,IO
227 INTEGER,
INTENT(IN) :: ttype
228 CHARACTER(LEN=32),
INTENT(IN) :: tname
231 CHARACTER(LEN=32) :: order_str,cfl_str,stoptime_str,dtmax_str,beta_str
232 CHARACTER(LEN=32) :: info_str,shear_direction
235 CALL this%InitLogging(ttype,tname)
237 IF (.NOT.physics%Initialized().OR..NOT.mesh%Initialized()) &
238 CALL this%Error(
"InitTimedisc",
"physics and/or mesh module uninitialized")
242 this%xfluxdydz(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,physics%VNUM), &
243 this%yfluxdzdx(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,physics%VNUM), &
244 this%zfluxdxdy(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,physics%VNUM), &
245 this%amax(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,3), &
246 this%tol_abs(physics%VNUM), &
247 this%dtmean, this%dtstddev, &
251 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory.")
255 CALL physics%new_statevector(this%pvar,primitive)
256 CALL physics%new_statevector(this%ptmp,primitive)
257 CALL physics%new_statevector(this%cvar,conservative)
258 CALL physics%new_statevector(this%ctmp,conservative)
259 CALL physics%new_statevector(this%cold,conservative)
260 CALL physics%new_statevector(this%geo_src,conservative)
261 CALL physics%new_statevector(this%src,conservative)
262 CALL physics%new_statevector(this%rhs,conservative)
263 NULLIFY(this%cerr,this%cerr_max)
266 this%pvar%data1d(:) = 0.
267 this%ptmp%data1d(:) = 0.
268 this%ctmp%data1d(:) = 0.
269 this%cvar%data1d(:) = 0.
270 this%cold%data1d(:) = 0.
271 this%geo_src%data1d(:) = 0.
272 this%src%data1d(:) = 0.
273 this%rhs%data1d(:) = 0.
286 CALL getattr(config,
"starttime", this%time, 0.0)
287 CALL getattr(config,
"method", method)
288 CALL getattr(config,
"stoptime", this%stoptime)
289 this%dt = this%stoptime
295 CALL getattr(config,
"cfl", this%cfl, 0.4)
298 CALL getattr(config,
"dtlimit", this%dtlimit, epsilon(this%dtlimit)*this%stoptime)
301 CALL getattr(config,
"dtmax", this%dtmax, 5.0)
304 CALL getattr(config,
"maxiter", this%maxiter, 0)
307 CALL getattr(config,
"tol_rel", this%tol_rel, 0.01)
310 this%tol_abs(:) = 0.001
311 CALL getattr(config,
"tol_abs", this%tol_abs, this%tol_abs)
314 CALL getattr(config,
"rhstype", this%rhstype, 0)
315 IF (this%rhstype.NE.0.AND.physics%VDIM.NE.2)
THEN 316 CALL this%Error(
"InitTimedisc",
"Alternative rhstype only works in 2D.")
320 CALL getattr(config,
"beta", this%beta, 0.08)
331 CALL getattr(config,
"always_update_bccsound", d, 1)
333 this%always_update_bccsound = .false.
335 this%always_update_bccsound = .true.
340 CALL getattr(config,
"checkdata", this%checkdatabm,
check_all)
343 CALL getattr(config,
"pmin", this%pmin, tiny(this%pmin))
346 CALL getattr(config,
"tmin", this%tmin, tiny(this%tmin))
349 CALL getattr(config,
"rhomin", this%rhomin, tiny(this%rhomin))
351 CALL getattr(config,
"output/"//trim(physics%pvarname(1)), d, 1)
353 CALL this%SetOutput(mesh,physics,config,io)
356 IF(mesh%use_fargo.EQ.1)
THEN 358 SELECT TYPE(phys => physics)
361 SELECT TYPE(geo=>mesh%Geometry)
363 IF (mesh%JNUM.LT.2)
CALL this%Error(
"InitTimedisc", &
364 "fargo advection needs more the one cell in y-direction")
367 this%w(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
368 this%delxy(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
369 this%shift(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
371 this%buf(physics%VNUM+physics%PNUM,1:mesh%MINJNUM), &
375 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory for fargo advection.")
379 IF (mesh%JNUM.LT.2)
CALL this%Error(
"InitTimedisc", &
380 "fargo advection needs more the one cell in y-direction")
383 this%w(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
384 this%delxy(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
385 this%shift(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
387 this%buf(physics%VNUM+physics%PNUM,1:mesh%MINJNUM), &
391 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory for fargo advection.")
394 IF(mesh%shear_dir.EQ.2)
THEN 396 this%w(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
397 this%delxy(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
398 this%shift(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX), &
400 this%buf(physics%VNUM+physics%PNUM,1:mesh%MINJNUM), &
404 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory for fargo advection.")
406 ELSE IF(mesh%shear_dir.EQ.1)
THEN 408 this%w(mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX), &
409 this%delxy(mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX), &
410 this%shift(mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX), &
412 this%buf(physics%VNUM+physics%PNUM,1:mesh%MININUM), &
416 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory for fargo advection.")
419 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory for fargo advection.")
424 CALL this%Warning(
"InitTimedisc", &
425 "fargo has been disabled, because the geometry is not supported.")
430 CALL this%Warning(
"InitTimedisc",
"fargo has been disabled, because the physics is not supported.")
433 SELECT CASE(mesh%FARGO)
438 this%shift(:,:) = 0.0
440 this%dq%data1d(:) = 0.0
442 this%dql%data1d(:) = 0.0
444 this%flux%data1d(:) = 0.0
446 IF(mesh%shear_dir.EQ.2)
THEN 447 this%w(:,:) = -mesh%Q*mesh%omega*mesh%bcenter(:,mesh%JMIN,:,1)
448 this%shift(:,:) = 0.0
449 shear_direction =
"west<->east" 450 ELSE IF(mesh%shear_dir.EQ.1)
THEN 451 this%w(:,:) = mesh%Q*mesh%omega*mesh%bcenter(mesh%IMIN,:,:,2)
452 this%shift(:,:) = 0.0
453 shear_direction =
"south<->north" 456 this%dq%data1d(:) = 0.0
458 this%dql%data1d(:) = 0.0
460 this%flux%data1d(:) = 0.0
462 ELSE IF (mesh%use_fargo.EQ.0)
THEN 465 CALL this%Error(
"InitTimedisc",
"unknown fargo advection scheme")
469 WRITE (order_str,
'(I0)') this%GetOrder()
470 WRITE (cfl_str,
'(F4.2)') this%GetCFL()
471 WRITE (stoptime_str,
'(ES10.4)') this%stoptime
472 WRITE (dtmax_str,
'(ES10.4)') this%dtmax
473 WRITE (beta_str,
'(ES10.4)') this%beta
474 CALL this%Info(
" TIMEDISC-> ODE solver: " //trim(this%GetName()))
475 CALL this%Info(
" order: " //trim(order_str))
476 CALL this%Info(
" CFL number: " //trim(cfl_str))
477 CALL this%Info(
" dtmax: " //trim(dtmax_str))
478 CALL this%Info(
" stoptime: " //trim(stoptime_str))
479 CALL this%Info(
" beta: " //trim(beta_str))
481 IF (this%tol_rel.LT.1.0.AND.this%order.GT.1)
THEN 483 CALL physics%new_statevector(this%cerr,conservative)
484 this%cerr%data1d(:) = 0.
486 WRITE (info_str,
'(ES7.1)') this%tol_rel*100
487 CALL this%Info(
" step size control: enabled")
488 CALL this%Info(
" rel. precision: "//trim(info_str)//
" %")
490 WRITE (info_str,
'(A)')
"disabled" 492 IF (mesh%FARGO.NE.0) &
493 CALL this%Info(
" fargo: " //trim(
fargo_method(mesh%FARGO)))
494 IF(mesh%FARGO.EQ.3) &
495 CALL this%Info(
" shear-direction: " //trim(shear_direction))
496 SELECT CASE(this%rhstype)
500 IF (.NOT.
ASSOCIATED(this%w))
THEN 501 ALLOCATE(this%w(mesh%IGMIN:mesh%IGMAX,mesh%KGMIN:mesh%KGMAX),stat = err)
503 CALL this%Error(
"InitTimedisc",
"Unable to allocate memory for special RHS time stepping.")
507 CALL this%Info(
" special rhs: enabled")
509 CALL this%Error(
"InitTimedisc",
"unknown rhstype")
514 SUBROUTINE setoutput(this,Mesh,Physics,config,IO)
517 CLASS(timedisc_base),
INTENT(INOUT) :: this
518 CLASS(mesh_base),
INTENT(IN) :: Mesh
519 CLASS(physics_base),
INTENT(IN) :: Physics
520 TYPE(Dict_TYP),
POINTER :: config,IO
522 INTEGER :: valwrite,i
523 CHARACTER(LEN=128) :: key,pvar_key
524 LOGICAL :: writeSolution
527 CALL getattr(config,
"output/error", valwrite, 0)
528 IF((valwrite.EQ.1).AND.this%tol_rel.LE.1.0)
THEN 529 this%write_error = .true.
530 CALL physics%new_statevector(this%cerr_max,conservative)
531 this%cerr_max%data1d(:) = 0.
533 this%write_error = .false.
537 CALL getattr(config,
"output/solution", valwrite, 0)
538 IF(valwrite.EQ.1)
THEN 539 writesolution = .true.
540 CALL physics%new_statevector(this%solution,primitive)
542 NULLIFY(this%solution)
543 writesolution = .false.
546 CALL getattr(config,
"output/time", valwrite, 1)
548 CALL setattr(io,
"time", ref(this%time))
552 key = trim(physics%pvarname(i))
555 CALL getattr(config,
"output/" // trim(key), valwrite, 1)
557 IF (valwrite.EQ.1)
THEN 558 CALL setattr(io, trim(key), &
559 this%pvar%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
562 IF(writesolution)
THEN 563 CALL setattr(io, trim(key)//
"_solution", &
564 this%solution%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
568 key = trim(physics%cvarname(i))
569 IF(key.EQ.pvar_key) key = trim(key) //
"_cvar" 571 CALL getattr(config,
"output/" // trim(key), valwrite, 0)
573 IF (valwrite.EQ.1)
THEN 574 CALL setattr(io, trim(key), &
575 this%cvar%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
578 key = trim(physics%cvarname(i))
579 IF(this%write_error)
THEN 580 CALL setattr(io, trim(key) //
"_error", &
581 this%cerr_max%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
585 CALL getattr(config,
"output/" //
"geometrical_sources", valwrite, 0)
586 IF (valwrite.EQ.1)
THEN 587 CALL setattr(io, trim(key)//
"_geo_src", &
588 this%geo_src%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
592 CALL getattr(config,
"output/" //
"external_sources", valwrite, 0)
593 IF (valwrite.EQ.1)
THEN 594 CALL setattr(io, trim(key)//
"_src", &
595 this%src%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
599 CALL getattr(config,
"output/" //
"rhs", valwrite, 0)
600 IF (valwrite.EQ.1)
THEN 601 CALL setattr(io, trim(key)//
"_rhs", &
602 this%rhs%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
607 CALL getattr(config,
"output/" //
"fluxes", valwrite, 0)
608 IF (valwrite.EQ.1)
THEN 609 CALL setattr(io, trim(key)//
"_xfluxdydz", &
610 this%xfluxdydz(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
611 CALL setattr(io, trim(key)//
"_yfluxdzdx", &
612 this%yfluxdzdx(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
613 CALL setattr(io, trim(key)//
"_zfluxdxdy", &
614 this%zfluxdxdy(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,i))
619 CALL getattr(config,
"output/" //
"bflux", valwrite, 0)
620 IF(valwrite.EQ.1)
THEN 621 ALLOCATE(this%bflux(physics%VNUM,6))
622 CALL setattr(io,
"bflux", this%bflux)
629 SUBROUTINE integrationstep(this,Mesh,Physics,Sources,Fluxes,iter,config,IO)
631 CLASS(timedisc_base),
INTENT(INOUT) :: this
632 CLASS(mesh_base),
INTENT(INOUT) :: Mesh
633 CLASS(physics_base),
INTENT(INOUT) :: Physics
634 CLASS(sources_base),
POINTER :: Sources
635 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
637 TYPE(Dict_TYP),
POINTER :: config,IO
639 REAL :: err,dtold,dt,time
641 INTENT(INOUT) :: iter
644 IF (mesh%FARGO.GT.0)
THEN 645 IF (mesh%shear_dir.EQ.1.AND.mesh%FARGO.EQ.3)
THEN 646 CALL physics%SubtractBackgroundVelocityX(mesh,this%w,this%pvar,this%cvar)
648 CALL physics%SubtractBackgroundVelocityY(mesh,this%w,this%pvar,this%cvar)
658 this%dtmincause = this%dtcause
661 timestep:
DO WHILE (time+dt.LE.this%time+this%dt)
664 CALL this%SolveODE(mesh,physics,sources,fluxes,time,dt,err)
667 CALL this%AcceptSolution(mesh,physics,sources,fluxes,time,dtold,iter)
669 CALL this%RejectSolution(mesh,physics,sources,fluxes,time,dt)
672 IF (dt.LT.this%dtlimit) &
683 this%dt = time - this%time
689 IF (mesh%FARGO.GT.0)
THEN 690 IF (mesh%shear_dir.EQ.1)
THEN 691 CALL this%FargoAdvectionX(fluxes,mesh,physics,sources)
693 CALL this%FargoAdvectionY(fluxes,mesh,physics,sources)
709 REAL :: maxerr,dtold,dtnew
713 INTENT(IN) :: maxerr,dtold
714 INTENT(INOUT) ::
this 717 IF (
this%tol_rel.GE.1.0)
THEN 726 IF(maxerr.GT.0.)
THEN 736 IF (
this%maxerrold.GT.0.)
THEN 737 dtnew = dttmp * exp(-
this%beta*log(
this%maxerrold/maxerr))
743 IF (maxerr.LT.1.0)
THEN 745 dtnew = min(dtnew,4.*dtold)
752 IF (dtnew.GT.dtold) dtnew = dttmp
754 dtnew = max(dtnew,0.25*dtold)
758 this%maxerrold = maxerr
764 REAL FUNCTION calctimestep(this,Mesh,Physics,Sources,Fluxes,time,dtcause)
RESULT(dt)
773 REAL,
INTENT(IN) :: time
774 INTEGER,
INTENT(INOUT) :: dtcause
777 REAL :: dt_cfl, dt_src
778 REAL :: invdt_x,invdt_y,invdt_z
782 IF (.NOT.
this%always_update_bccsound)
THEN 783 SELECT TYPE(phys => physics)
785 SELECT TYPE(pvar =>
this%pvar)
787 CALL phys%UpdateSoundSpeed(pvar)
792 SELECT TYPE(phys => physics)
793 TYPE IS(physics_eulerisotherm)
794 SELECT TYPE(pvar =>
this%pvar)
795 CLASS IS(statevector_eulerisotherm)
796 CALL phys%CalculateWaveSpeeds(mesh,pvar,fluxes%minwav,fluxes%maxwav)
799 SELECT TYPE(pvar =>
this%pvar)
801 CALL phys%CalculateWaveSpeeds(mesh,pvar,fluxes%minwav,fluxes%maxwav)
806 IF ((mesh%JNUM.EQ.1).AND.(mesh%KNUM.EQ.1))
THEN 808 invdt = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dlx%data1d(:))
809 ELSE IF ((mesh%INUM.EQ.1).AND.(mesh%KNUM.EQ.1))
THEN 811 invdt = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dly%data1d(:))
812 ELSE IF ((mesh%INUM.EQ.1).AND.(mesh%JNUM.EQ.1))
THEN 814 invdt = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dlz%data1d(:))
815 ELSE IF ((mesh%INUM.GT.1).AND.(mesh%JNUM.GT.1).AND.(mesh%KNUM.EQ.1))
THEN 817 invdt = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dlx%data1d(:) &
818 + max(fluxes%maxwav%data2d(:,2),-fluxes%minwav%data2d(:,2)) / mesh%dly%data1d(:))
819 ELSE IF ((mesh%INUM.GT.1).AND.(mesh%KNUM.GT.1).AND.(mesh%JNUM.EQ.1))
THEN 821 invdt = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dlx%data1d(:) &
822 + max(fluxes%maxwav%data2d(:,2),-fluxes%minwav%data2d(:,2)) / mesh%dlz%data1d(:))
823 ELSE IF ((mesh%JNUM.GT.1).AND.(mesh%KNUM.GT.1).AND.(mesh%INUM.EQ.1))
THEN 825 invdt = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dly%data1d(:) &
826 + max(fluxes%maxwav%data2d(:,2),-fluxes%minwav%data2d(:,2)) / mesh%dlz%data1d(:))
832 invdt_x = maxval(max(fluxes%maxwav%data2d(:,1),-fluxes%minwav%data2d(:,1)) / mesh%dlx%data1d(:))
833 invdt_y = maxval(max(fluxes%maxwav%data2d(:,2),-fluxes%minwav%data2d(:,2)) / mesh%dly%data1d(:))
834 invdt_z = maxval(max(fluxes%maxwav%data2d(:,3),-fluxes%minwav%data2d(:,3)) / mesh%dlz%data1d(:))
835 invdt = max(invdt_y,invdt_z,invdt_x)
842 dt_cfl =
this%cfl / invdt
847 IF (
ASSOCIATED(sources))
THEN 850 CALL sources%CalcTimestep(mesh,physics,fluxes,
this%pvar,
this%cvar,time,dt_src,dtcause)
851 dt = min(dt_cfl,dt_src)
857 SUBROUTINE acceptsolution(this,Mesh,Physics,Sources,Fluxes,time,dt,iter)
860 CLASS(timedisc_base),
INTENT(INOUT) :: this
861 CLASS(mesh_base),
INTENT(IN) :: Mesh
862 CLASS(physics_base),
INTENT(INOUT) :: Physics
863 CLASS(sources_base),
POINTER :: Sources
864 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
869 REAL,
DIMENSION(:),
POINTER :: bflux,bfold
871 INTENT(INOUT) :: time,dt
874 this%dtaccept = this%dtaccept + 1
875 dtmeanold = this%dtmean
876 this%dtmean = this%dtmean + (dt - this%dtmean)/this%dtaccept
877 this%dtstddev = this%dtstddev + (dt - dtmeanold)*(dt-this%dtmean)
878 CALL this%ComputeRHS(mesh,physics,sources,fluxes,time,dt,this%pvar,&
879 this%cvar,this%checkdatabm,this%rhs)
880 this%cold%data1d(:) = this%cvar%data1d(:)
881 IF (mesh%INUM.GT.1)
THEN 885 bflux(1:
SIZE(fluxes%bxflux)) => fluxes%bxflux
886 bfold(1:
SIZE(fluxes%bxfold)) => fluxes%bxfold
890 IF (mesh%JNUM.GT.1)
THEN 891 bflux(1:
SIZE(fluxes%byflux)) => fluxes%byflux
892 bfold(1:
SIZE(fluxes%byfold)) => fluxes%byfold
896 IF (mesh%KNUM.GT.1)
THEN 897 bflux(1:
SIZE(fluxes%bzflux)) => fluxes%bzflux
898 bfold(1:
SIZE(fluxes%bzfold)) => fluxes%bzfold
905 SUBROUTINE rejectsolution(this,Mesh,Physics,Sources,Fluxes,time,dt)
908 CLASS(timedisc_base),
INTENT(INOUT) :: this
909 CLASS(mesh_base),
INTENT(IN) :: Mesh
910 CLASS(physics_base),
INTENT(INOUT) :: Physics
911 CLASS(sources_base),
POINTER :: Sources
912 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
918 this%cvar%data1d(:) = this%cold%data1d(:)
920 CALL this%ComputeRHS(mesh,physics,sources,fluxes,time,dt,this%pvar, &
922 fluxes%bxflux(:,:,:,:) = fluxes%bxfold(:,:,:,:)
923 fluxes%byflux(:,:,:,:) = fluxes%byfold(:,:,:,:)
924 fluxes%bzflux(:,:,:,:) = fluxes%bzfold(:,:,:,:)
926 this%n_adj = this%n_adj + 1
929 IF (dt.LT.this%dtmin)
THEN 931 this%dtmincause = this%dtcause
936 FUNCTION computeerror(this,Mesh,Physics,cvar_high,cvar_low)
RESULT(maxerr)
949 REAL :: rel_err(physics%vnum)
954 this%cerr%data2d(:,l) = abs(cvar_high%data2d(:,l)-cvar_low%data2d(:,l)) &
955 / (
this%tol_rel*abs(cvar_high%data2d(:,l)) +
this%tol_abs(l))
957 rel_err(l) = maxval(
this%cerr%data2d(:,l),mask=mesh%without_ghost_zones%mask1d(:))
959 IF (
this%write_error) &
960 this%cerr_max%data2d(:,l) = max(
this%cerr_max%data2d(:,l),
this%cerr%data2d(:,l))
964 maxerr = maxval(rel_err(:))
969 mesh%comm_cart,ierror)
992 SUBROUTINE computerhs(this,Mesh,Physics,Sources,Fluxes,time,dt,pvar,cvar,checkdatabm,rhs)
997 CLASS(timedisc_base),
INTENT(INOUT) :: this
998 CLASS(mesh_base),
INTENT(IN) :: Mesh
999 CLASS(physics_base),
INTENT(INOUT) :: Physics
1000 CLASS(sources_base),
POINTER :: Sources
1001 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
1002 REAL,
INTENT(IN) :: time, dt
1003 CLASS(marray_compound),
INTENT(INOUT):: pvar,cvar,rhs
1004 INTEGER,
INTENT(IN) :: checkdatabm
1007 LOGICAL :: have_potential
1010 REAL,
DIMENSION(:,:,:,:),
POINTER :: pot
1011 CLASS(sources_base),
POINTER :: sp
1012 CLASS(sources_gravity),
POINTER :: grav
1015 SELECT CASE(mesh%FARGO)
1019 CALL physics%AddBackgroundVelocityY(mesh,this%w,pvar,cvar)
1025 IF (mesh%shear_dir.EQ.1)
THEN 1026 CALL physics%SubtractBackgroundVelocityX(mesh,this%w,pvar,cvar)
1027 ELSE IF (mesh%shear_dir.EQ.2)
THEN 1028 CALL physics%SubtractBackgroundVelocityY(mesh,this%w,pvar,cvar)
1038 CALL this%boundary%CenterBoundary(mesh,physics,t,pvar,cvar)
1041 this%tmin.GT.1.e-10)
THEN 1042 SELECT TYPE(p => pvar)
1044 SELECT TYPE(c => cvar)
1047 p%pressure%data1d(:) = max(p%pressure%data1d(:), &
1048 p%density%data1d(:)*physics%Constants%RG/physics%MU*this%TMIN)
1049 CALL physics%Convert2Conservative(p,c)
1055 physics%PRESSURE.GT.0)
THEN 1058 SELECT TYPE(p => pvar)
1060 SELECT TYPE(c => cvar)
1063 p%pressure%data1d(:) &
1064 = max(p%pressure%data1d(:),this%pmin)
1065 CALL physics%Convert2Conservative(p,c)
1071 IF (this%always_update_bccsound)
THEN 1072 SELECT TYPE(phys => physics)
1074 SELECT TYPE(pvar => this%pvar)
1076 CALL phys%UpdateSoundSpeed(pvar)
1083 CALL this%CheckData(mesh,physics,fluxes,pvar,cvar,checkdatabm)
1086 CALL physics%GeometricalSources(mesh,pvar,cvar,this%geo_src)
1089 IF (
ASSOCIATED(sources)) &
1090 CALL sources%ExternalSources(mesh,fluxes,physics, &
1091 t,dt,pvar,cvar,this%src)
1096 SELECT CASE(mesh%FARGO)
1099 CALL physics%AddFargoSources(mesh,this%w,pvar,cvar,this%geo_src)
1101 CALL physics%SubtractBackgroundVelocityY(mesh,this%w,pvar,cvar)
1111 CALL fluxes%CalculateFluxes(mesh,physics,pvar,cvar,this%xfluxdydz, &
1112 this%yfluxdzdx,this%zfluxdxdy)
1117 DO l=1,physics%VNUM+physics%PNUM
1119 DO k=mesh%KMIN,mesh%KMAX
1121 DO j=mesh%JMIN,mesh%JMAX
1123 rhs%data4d(mesh%IMIN-mesh%Ip1,j,k,l) = mesh%dy*mesh%dz * this%xfluxdydz(mesh%IMIN-mesh%Ip1,j,k,l)
1124 rhs%data4d(mesh%IMAX+mesh%Ip1,j,k,l) = -mesh%dy*mesh%dz * this%xfluxdydz(mesh%IMAX,j,k,l)
1128 DO k=mesh%KMIN,mesh%KMAX
1130 DO i=mesh%IMIN,mesh%IMAX
1132 rhs%data4d(i,mesh%JMIN-mesh%Jp1,k,l) = mesh%dz*mesh%dx * this%yfluxdzdx(i,mesh%JMIN-mesh%Jp1,k,l)
1133 rhs%data4d(i,mesh%JMAX+mesh%Jp1,k,l) = -mesh%dz*mesh%dx * this%yfluxdzdx(i,mesh%JMAX,k,l)
1137 DO j=mesh%JMIN,mesh%JMAX
1139 DO i=mesh%IMIN,mesh%IMAX
1141 rhs%data4d(i,j,mesh%KMIN-mesh%Kp1,l) = mesh%dx*mesh%dy * this%zfluxdxdy(i,j,mesh%KMIN-mesh%Kp1,l)
1142 rhs%data4d(i,j,mesh%KMAX+mesh%Kp1,l) = -mesh%dx*mesh%dy * this%zfluxdxdy(i,j,mesh%KMAX,l)
1147 SELECT CASE(this%rhstype)
1150 DO l=1,physics%VNUM+physics%PNUM
1151 DO k=mesh%KMIN,mesh%KMAX
1152 DO j=mesh%JMIN,mesh%JMAX
1154 DO i=mesh%IMIN,mesh%IMAX
1156 rhs%data4d(i,j,k,l) = &
1157 mesh%dydzdV%data3d(i,j,k)*(this%xfluxdydz(i,j,k,l) - this%xfluxdydz(i-mesh%Ip1,j,k,l)) &
1158 + mesh%dzdxdV%data3d(i,j,k)*(this%yfluxdzdx(i,j,k,l) - this%yfluxdzdx(i,j-mesh%Jp1,k,l)) &
1159 + mesh%dxdydV%data3d(i,j,k)*(this%zfluxdxdy(i,j,k,l) - this%zfluxdxdy(i,j,k-mesh%Kp1,l)) &
1160 - this%geo_src%data4d(i,j,k,l) - this%src%data4d(i,j,k,l)
1171 IF (
ASSOCIATED(sp).EQV..false.)
RETURN 1181 have_potential = .false.
1182 IF(
ASSOCIATED(grav))
THEN 1183 IF(.NOT.grav%addtoenergy)
THEN 1184 pot => mesh%RemapBounds(grav%pot%data4d(:,:,:,:))
1185 have_potential=.true.
1191 DO k=mesh%KMIN-mesh%KP1,mesh%KMAX
1192 DO j=mesh%JMIN-mesh%JP1,mesh%JMAX
1194 DO i=mesh%IMIN-mesh%IP1,mesh%IMAX
1195 wp = 0.5*(this%w(i,k)+this%w(i+1,k)) + mesh%hy%faces(i+1,j,k,1)*mesh%OMEGA
1196 IF(physics%PRESSURE.GT.0)
THEN 1197 this%xfluxdydz(i,j,k,physics%ENERGY) &
1198 = this%xfluxdydz(i,j,k,physics%ENERGY) &
1199 + wp * (0.5 * wp * this%xfluxdydz(i,j,k,physics%DENSITY) &
1200 + this%xfluxdydz(i,j,k,physics%YMOMENTUM))
1201 IF (have_potential)
THEN 1202 this%xfluxdydz(i,j,k,physics%ENERGY) = this%xfluxdydz(i,j,k,physics%ENERGY) + pot(i,j,k,2)*this%xfluxdydz(i,j,k,physics%DENSITY)
1206 this%xfluxdydz(i,j,k,physics%YMOMENTUM) &
1207 = (this%xfluxdydz(i,j,k,physics%YMOMENTUM) &
1208 + wp * this%xfluxdydz(i,j,k,physics%DENSITY)) * mesh%hy%faces(i+1,j,k,1)
1210 wp = this%w(i,k) + mesh%radius%bcenter(i,j,k)*mesh%OMEGA
1211 IF(physics%PRESSURE.GT.0)
THEN 1212 this%yfluxdzdx(i,j,k,physics%ENERGY) &
1213 = this%yfluxdzdx(i,j,k,physics%ENERGY) &
1214 + wp * ( 0.5 * wp * this%yfluxdzdx(i,j,k,physics%DENSITY) &
1215 + this%yfluxdzdx(i,j,k,physics%YMOMENTUM))
1216 IF (have_potential)
THEN 1217 this%yfluxdzdx(i,j,k,physics%ENERGY) = this%yfluxdzdx(i,j,k,physics%ENERGY) + pot(i,j,k,3)*this%yfluxdzdx(i,j,k,physics%DENSITY)
1221 this%yfluxdzdx(i,j,k,physics%YMOMENTUM) &
1222 = this%yfluxdzdx(i,j,k,physics%YMOMENTUM) &
1223 + wp * this%yfluxdzdx(i,j,k,physics%DENSITY)
1229 SELECT TYPE (phys => physics)
1231 DO k=mesh%KMIN,mesh%KMAX
1232 DO j=mesh%JMIN,mesh%JMAX
1234 DO i=mesh%IMIN,mesh%IMAX
1235 wp = pvar%data4d(i,j,k,physics%YVELOCITY) + this%w(i,k) + mesh%radius%bcenter(i,j,k)*mesh%OMEGA
1236 this%geo_src%data4d(i,j,k,physics%XMOMENTUM) &
1237 = pvar%data4d(i,j,k,physics%DENSITY) * wp**2 * mesh%cyxy%bcenter(i,j,k) &
1238 + pvar%data4d(i,j,k,physics%DENSITY) * pvar%data4d(i,j,k,physics%XVELOCITY) * wp * mesh%cxyx%bcenter(i,j,k)
1240 this%geo_src%data4d(i,j,k,physics%YMOMENTUM) &
1241 = cvar%data4d(i,j,k,physics%XMOMENTUM) &
1242 * ( pvar%data4d(i,j,k,physics%XVELOCITY) * mesh%cxyx%center(i,j,k) )
1244 IF(physics%PRESSURE.GT.0)
THEN 1245 this%geo_src%data4d(i,j,k,physics%XMOMENTUM) &
1246 = this%geo_src%data4d(i,j,k,physics%XMOMENTUM) &
1247 +pvar%data4d(i,j,k,physics%PRESSURE) &
1248 *( mesh%cyxy%center(i,j,k) + mesh%czxz%center(i,j,k) )
1249 this%geo_src%data4d(i,j,k,physics%YMOMENTUM) &
1250 = this%geo_src%data4d(i,j,k,physics%YMOMENTUM) &
1251 + pvar%data4d(i,j,k,physics%PRESSURE) &
1252 *( mesh%cxyx%center(i,j,k) + mesh%czyz%center(i,j,k) )
1253 this%geo_src%data4d(i,j,k,physics%ENERGY) = 0.
1256 this%geo_src%data4d(i,j,k,physics%XMOMENTUM) &
1257 = this%geo_src%data4d(i,j,k,physics%XMOMENTUM) &
1258 +pvar%data4d(i,j,k,physics%DENSITY)*phys%bccsound%data3d(i,j,k)**2 &
1259 * ( mesh%cyxy%center(i,j,k) + mesh%czxz%center(i,j,k) )
1260 this%geo_src%data4d(i,j,k,physics%YMOMENTUM) &
1261 = this%geo_src%data4d(i,j,k,physics%YMOMENTUM) &
1262 + pvar%data4d(i,j,k,physics%DENSITY)*phys%bccsound%data3d(i,j,k)**2 &
1263 *( mesh%cxyx%center(i,j,k) + mesh%czyz%center(i,j,k) )
1274 DO l=1,physics%VNUM+physics%PNUM
1276 DO k=mesh%KMIN,mesh%KMAX
1277 DO j=mesh%JMIN,mesh%JMAX
1279 DO i=mesh%IMIN,mesh%IMAX
1281 IF(l.EQ.physics%YMOMENTUM)
THEN 1282 rhs%data4d(i,j,k,l) = mesh%dydzdV%data3d(i,j,k)*(this%xfluxdydz(i,j,k,l) - this%xfluxdydz(i-1,j,k,l)) &
1283 / mesh%hy%center(i,j,k)
1285 rhs%data4d(i,j,k,l) = mesh%dydzdV%data3d(i,j,k)*(this%xfluxdydz(i,j,k,l) - this%xfluxdydz(i-1,j,k,l))
1288 rhs%data4d(i,j,k,l) = rhs%data4d(i,j,k,l) &
1289 + mesh%dzdxdV%data3d(i,j,k)*(this%yfluxdzdx(i,j,k,l) - this%yfluxdzdx(i,j-1,k,l))
1295 DO k=mesh%KMIN,mesh%KMAX
1296 DO j=mesh%JMIN,mesh%JMAX
1298 DO i=mesh%IMIN,mesh%IMAX
1299 wp = this%w(i,k) + mesh%radius%bcenter(i,j,k) * mesh%OMEGA
1300 rhs%data4d(i,j,k,physics%YMOMENTUM) = rhs%data4d(i,j,k,physics%YMOMENTUM) &
1301 - wp * rhs%data4d(i,j,k,physics%DENSITY)
1302 IF(physics%PRESSURE.GT.0)
THEN 1303 rhs%data4d(i,j,k,physics%ENERGY) = rhs%data4d(i,j,k,physics%ENERGY) &
1304 - wp*( rhs%data4d(i,j,k,physics%YMOMENTUM) &
1305 + 0.5 * wp* rhs%data4d(i,j,k,physics%DENSITY))
1306 IF (have_potential)
THEN 1307 rhs%data4d(i,j,k,physics%ENERGY) = &
1308 rhs%data4d(i,j,k,physics%ENERGY) - pot(i,j,k,1) * rhs%data4d(i,j,k,physics%DENSITY)
1316 DO l=1,physics%VNUM+physics%PNUM
1318 DO k=mesh%KMIN,mesh%KMAX
1319 DO j=mesh%JMIN,mesh%JMAX
1321 DO i=mesh%IMIN,mesh%IMAX
1323 rhs%data4d(i,j,k,l) = rhs%data4d(i,j,k,l) - this%geo_src%data4d(i,j,k,l) - this%src%data4d(i,j,k,l)
1333 SUBROUTINE checkdata(this,Mesh,Physics,Fluxes,pvar,cvar,checkdatabm)
1338 CLASS(timedisc_base),
INTENT(INOUT) :: this
1339 CLASS(mesh_base),
INTENT(IN) :: Mesh
1340 CLASS(physics_base),
INTENT(INOUT) :: Physics
1341 CLASS(fluxes_base),
INTENT(IN) :: Fluxes
1342 CLASS(marray_compound),
INTENT(INOUT):: pvar,cvar
1343 INTEGER,
INTENT(IN) :: checkdatabm
1352 SELECT TYPE(phys => physics)
1354 val = minval(phys%bccsound%data1d(:))
1357 CALL this%Warning(
"CheckData",
"Illegal speed of sound value less than 0.")
1361 CALL this%Warning(
"CheckData",
"check speed of sound selected, but bccsound not defined")
1366 SELECT TYPE(p => pvar)
1368 val = minval(p%pressure%data3d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX, &
1369 mesh%KMIN:mesh%KMAX))
1370 IF(val.LT.this%pmin)
THEN 1372 CALL this%Warning(
"CheckData",
"Pressure below allowed pmin value.")
1380 SELECT TYPE(p => pvar)
1382 val = minval(p%density%data3d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX, &
1383 mesh%KMIN:mesh%KMAX))
1384 IF(val.LT.this%rhomin)
THEN 1386 CALL this%Warning(
"CheckData",
"Density below allowed rhomin value.")
1393 IF(any((cvar%data1d.NE.cvar%data1d).OR.(pvar%data1d.NE.pvar%data1d)))
THEN 1395 CALL this%Warning(
"CheckData",
"Found NaN in pvar or cvar.")
1398 IF(any((cvar%data1d.GT.huge(cvar%data1d)).OR.pvar%data1d.GT.huge(pvar%data1d)))
THEN 1400 CALL this%Warning(
"CheckData",
"Found Infinity in pvar or cvar.")
1406 CALL mpi_allreduce(mpi_in_place, this%break, 1, mpi_logical, mpi_lor, &
1407 mesh%comm_cart, err)
1411 PURE FUNCTION getorder(this)
RESULT(odr)
1420 PURE FUNCTION getcfl(this)
RESULT(cfl)
1451 CLASS(timedisc_base),
INTENT(INOUT) :: this
1452 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
1453 CLASS(mesh_base),
INTENT(IN) :: Mesh
1454 CLASS(physics_base),
INTENT(INOUT) :: Physics
1455 CLASS(sources_base),
POINTER :: Sources
1459 CHARACTER(LEN=80) :: str
1460 INTEGER :: status(MPI_STATUS_SIZE)
1462 REAL :: mpi_buf(2*Mesh%GNUM)
1463 REAL,
DIMENSION(Mesh%JMIN:Mesh%JMAX) :: buf
1468 this%delxy(:,:) = this%w(:,:) * this%dt / mesh%dlx%data3d(mesh%IMIN,:,:)
1473 IF (mesh%dims(1).GT.1)
THEN 1474 CALL mpi_allreduce(mpi_in_place,this%delxy,(mesh%JGMAX-mesh%JGMIN+1)*(mesh%KGMAX-mesh%KGMIN+1), &
1481 DO k = mesh%KGMIN,mesh%KGMAX
1483 DO j = mesh%JGMIN,mesh%JGMAX
1484 this%shift(j,k) = nint(this%delxy(j,k))
1485 this%delxy(j,k) = this%delxy(j,k)-dble(this%shift(j,k))
1490 DO l=1,physics%VNUM+physics%PNUM
1491 this%dq%data3d(mesh%IGMIN,:,:) = this%cvar%data4d(mesh%IGMIN+1,:,:,l) - this%cvar%data4d(mesh%IGMIN,:,:,l)
1493 DO i=mesh%IGMIN+1,mesh%IGMAX-1
1494 this%dq%data3d(i,:,:) = this%cvar%data4d(i+1,:,:,l)-this%cvar%data4d(i,:,:,l)
1496 WHERE (sign(1.0,this%dq%data3d(i-1,:,:))*sign(1.0,this%dq%data3d(i,:,:)).GT.0)
1497 this%dql%data3d(i,:,:) = sign(min(abs(this%dq%data3d(i-1,:,:)),abs(this%dq%data3d(i,:,:))),this%dq%data3d(i-1,:,:))
1499 this%dql%data3d(i,:,:) = 0.
1503 DO i=mesh%IMIN-1,mesh%IMAX
1504 WHERE(this%delxy(:,:).GT.0.)
1505 this%flux%data3d(i,:,:) = this%cvar%data4d(i,:,:,l) + .5 * this%dql%data3d(i,:,:) * (1. - this%delxy(:,:))
1507 this%flux%data3d(i,:,:) = this%cvar%data4d(i+1,:,:,l) - .5*this%dql%data3d(i+1,:,:)*(1. + this%delxy(:,:))
1509 this%cvar%data4d(i,:,:,l) = this%cvar%data4d(i,:,:,l) - this%delxy(:,:)*(this%flux%data3d(i,:,:) - this%flux%data3d(i-1,:,:))
1570 DO l=1,physics%VNUM+physics%PNUM
1572 DO k=mesh%KGMIN,mesh%KGMAX
1574 DO j=mesh%JGMIN,mesh%JGMAX
1575 this%cvar%data4d(mesh%IMIN:mesh%IMAX,j,k,l) &
1576 = cshift(this%cvar%data4d(mesh%IMIN:mesh%IMAX,j,k,l),-this%shift(j,k),1)
1582 CALL physics%Convert2Primitive(this%cvar,this%pvar)
1584 CALL this%ComputeRHS(mesh,physics,sources,fluxes,this%time,0.,this%pvar,this%cvar,&
1585 this%checkdatabm,this%rhs)
1587 this%cold%data1d(:) = this%cvar%data1d(:)
1614 CLASS(timedisc_base),
INTENT(INOUT) :: this
1615 CLASS(fluxes_base),
INTENT(INOUT) :: Fluxes
1616 CLASS(mesh_base),
INTENT(IN) :: Mesh
1617 CLASS(physics_base),
INTENT(INOUT) :: Physics
1618 CLASS(sources_base),
POINTER :: Sources
1622 CHARACTER(LEN=80) :: str
1623 INTEGER :: status(MPI_STATUS_SIZE)
1625 REAL :: mpi_buf(2*Mesh%GNUM)
1626 REAL,
DIMENSION(Mesh%JMIN:Mesh%JMAX) :: buf
1631 this%delxy(:,:) = this%w(:,:) * this%dt / mesh%dlx%data3d(:,mesh%JMIN,:)
1636 IF (mesh%dims(2).GT.1)
THEN 1637 CALL mpi_allreduce(mpi_in_place,this%delxy,(mesh%IGMAX-mesh%IGMIN+1)*(mesh%KGMAX-mesh%KGMIN+1), &
1644 DO k = mesh%KGMIN,mesh%KGMAX
1646 DO i = mesh%IGMIN,mesh%IGMAX
1647 this%shift(i,k) = nint(this%delxy(i,k))
1648 this%delxy(i,k) = this%delxy(i,k)-dble(this%shift(i,k))
1653 DO l=1,physics%VNUM+physics%PNUM
1654 this%dq%data3d(:,mesh%JGMIN,:) = this%cvar%data4d(:,mesh%JGMIN+1,:,l) - this%cvar%data4d(:,mesh%JGMIN,:,l)
1656 DO j=mesh%JGMIN+1,mesh%JGMAX-1
1657 this%dq%data3d(:,j,:) = this%cvar%data4d(:,j+1,:,l)-this%cvar%data4d(:,j,:,l)
1659 WHERE (sign(1.0,this%dq%data3d(:,j-1,:))*sign(1.0,this%dq%data3d(:,j,:)).GT.0)
1660 this%dql%data3d(:,j,:) = sign(min(abs(this%dq%data3d(:,j-1,:)),abs(this%dq%data3d(:,j,:))),this%dq%data3d(:,j-1,:))
1662 this%dql%data3d(:,j,:) = 0.
1666 DO j=mesh%JMIN-1,mesh%JMAX
1667 WHERE(this%delxy(:,:).GT.0.)
1668 this%flux%data3d(:,j,:) = this%cvar%data4d(:,j,:,l) + .5 * this%dql%data3d(:,j,:) * (1. - this%delxy(:,:))
1670 this%flux%data3d(:,j,:) = this%cvar%data4d(:,j+1,:,l) - .5*this%dql%data3d(:,j+1,:)*(1. + this%delxy(:,:))
1672 this%cvar%data4d(:,j,:,l) = this%cvar%data4d(:,j,:,l) - this%delxy(:,:)*(this%flux%data3d(:,j,:) - this%flux%data3d(:,j-1,:))
1734 DO l=1,physics%VNUM+physics%PNUM
1736 DO k=mesh%KGMIN,mesh%KGMAX
1738 DO i=mesh%IGMIN,mesh%IGMAX
1739 this%cvar%data4d(i,mesh%JMIN:mesh%JMAX,k,l) &
1740 = cshift(this%cvar%data4d(i,mesh%JMIN:mesh%JMAX,k,l),-this%shift(i,k),1)
1746 CALL physics%Convert2Primitive(this%cvar,this%pvar)
1748 CALL this%ComputeRHS(mesh,physics,sources,fluxes,this%time,0.,this%pvar,this%cvar,&
1749 this%checkdatabm,this%rhs)
1751 this%cold%data1d(:) = this%cvar%data1d(:)
1763 CLASS(timedisc_base),
INTENT(INOUT) :: this
1764 CLASS(mesh_base),
INTENT(IN) :: Mesh
1765 CLASS(physics_base),
INTENT(INOUT) :: Physics
1766 CLASS(marray_compound),
INTENT(INOUT) :: pvar,cvar
1767 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%KGMIN:Mesh%KGMAX), &
1777 CALL physics%AddBackgroundVelocityY(mesh,w,pvar,cvar)
1778 SELECT TYPE(p => pvar)
1779 CLASS IS(statevector_eulerisotherm)
1780 DO k=mesh%KGMIN,mesh%KGMAX
1781 DO i=mesh%IGMIN,mesh%IGMAX
1783 wi = sum(p%velocity%data4d(i,mesh%JMIN:mesh%JMAX,k,2))
1786 IF(mesh%dims(2).GT.1)
THEN 1793 w(i,k) = wi / mesh%JNUM
1827 dir_omega_,accel_,centrot)
RESULT(velocity)
1837 REAL,
OPTIONAL,
INTENT(IN) :: dir_omega_(3)
1838 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX,Physics%VDIM), &
1839 OPTIONAL,
INTENT(IN) :: accel_
1840 REAL,
OPTIONAL,
INTENT(IN) :: centrot(3)
1841 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX,Physics%VDIM) &
1845 :: accel,dist_axis_projected,ephi_projected,eomega,tmpvec, &
1847 REAL :: omega2,dir_omega(3)
1850 ALLOCATE(accel,dist_axis_projected,ephi_projected,posvec,eomega,tmpvec,tmp, &
1852 IF (err.NE.0)
CALL this%Error(
"timedisc_base::GetCentrifugalVelocity", &
1853 "Unable to allocate memory.")
1864 IF (
PRESENT(dir_omega_))
THEN 1865 dir_omega(:) = dir_omega_(:)
1866 omega2 = sum(dir_omega(:)*dir_omega(:))
1868 IF (.NOT. (omega2.GT.0.0)) &
1869 CALL this%Error(
"timedisc_base::GetCentrifugalVelocity", &
1870 "omega must not be the zero vector")
1872 dir_omega(:) = dir_omega(:) / sqrt(omega2)
1875 dir_omega(1:3) = (/ 0.0, 0.0, 1.0 /)
1880 tmpvec%data2d(:,1) = dir_omega(1)
1881 tmpvec%data2d(:,2) = dir_omega(2)
1882 tmpvec%data2d(:,3) = dir_omega(3)
1883 CALL mesh%Geometry%Convert2Curvilinear(mesh%bcenter,tmpvec%data4d,eomega%data4d)
1891 IF (
PRESENT(centrot))
THEN 1892 IF ((mesh%rotsym.GT.0.0).AND.any(centrot(:).NE.0.0)) &
1893 CALL this%Error(
"timedisc_base::GetCentrifugalVelocity", &
1894 "if rotational symmetry is enabled center of rotation must be the origin")
1897 tmpvec%data4d(:,:,:,k) = mesh%bccart(:,:,:,k) - centrot(k)
1900 CALL mesh%Geometry%Convert2Curvilinear(mesh%bcenter,tmpvec%data4d,posvec%data4d)
1904 posvec%data4d = mesh%posvec%bcenter
1909 tmp%data1d(:) = sum(posvec%data2d(:,:)*eomega%data2d(:,:),dim=2)
1910 posvec%data2d(:,1) = posvec%data2d(:,1) - tmp%data1d(:)*eomega%data2d(:,1)
1911 posvec%data2d(:,2) = posvec%data2d(:,2) - tmp%data1d(:)*eomega%data2d(:,2)
1912 posvec%data2d(:,3) = posvec%data2d(:,3) - tmp%data1d(:)*eomega%data2d(:,3)
1915 tmp%data1d(:) = sqrt(sum(posvec%data2d(:,:)*posvec%data2d(:,:),dim=2))
1917 CALL cross_product(eomega%data2d(:,1),eomega%data2d(:,2),eomega%data2d(:,3), &
1918 posvec%data2d(:,1)/tmp%data1d(:),posvec%data2d(:,2)/tmp%data1d(:), &
1919 posvec%data2d(:,3)/tmp%data1d(:),tmpvec%data2d(:,1),tmpvec%data2d(:,2),tmpvec%data2d(:,3))
1922 SELECT TYPE(phys => physics)
1927 IF (btest(mesh%VECTOR_COMPONENTS,k-1))
THEN 1928 dist_axis_projected%data2d(:,l) = posvec%data2d(:,k)
1929 ephi_projected%data2d(:,l) = tmpvec%data2d(:,k)
1934 CALL this%Error(
"timedisc_base::GetCentrifugalVelocity", &
1935 "physics not supported")
1939 IF(
PRESENT(accel_))
THEN 1940 accel%data4d(:,:,:,:) = accel_(:,:,:,:)
1943 IF(
PRESENT(centrot))
THEN 1944 IF(any(centrot(:).NE.0.0)) &
1945 CALL this%Error(
"timedisc_base::GetCentrifugalVelocity", &
1946 "You are not allowed to define centrot without accel.")
1952 SELECT TYPE(phys => physics)
1958 CALL this%Error(
"timedisc_base::GetCentrifugalVelocity", &
1959 "physics not supported")
1961 SELECT TYPE(phys => physics)
1964 CALL this%ComputeRHS(mesh,phys,sources,fluxes,
this%time,0.0, &
1966 SELECT TYPE(pvar =>
this%pvar)
1968 SELECT TYPE(rhs =>
this%rhs)
1971 accel%data2d(:,k) = -rhs%momentum%data2d(:,k) / pvar%density%data1d(:)
1979 tmp%data1d(:) = sqrt(max(0.0,-sum(accel%data2d(:,:)*dist_axis_projected%data2d(:,:),dim=2)))
1983 velocity(:,:,:,k) = tmp%data3d(:,:,:) * ephi_projected%data4d(:,:,:,k)
1986 CALL accel%Destroy()
1987 CALL dist_axis_projected%Destroy()
1988 CALL ephi_projected%Destroy()
1989 CALL posvec%Destroy()
1990 CALL eomega%Destroy()
1991 CALL tmpvec%Destroy()
1993 DEALLOCATE(accel,dist_axis_projected,ephi_projected,posvec,eomega,tmpvec,tmp)
1997 ELEMENTAL SUBROUTINE cross_product(ax,ay,az,bx,by,bz,aXbx,aXby,aXbz)
2000 REAL,
INTENT(IN) :: ax,ay,az,bx,by,bz
2001 REAL,
INTENT(OUT) :: axbx,axby,axbz
2003 axbx = ay*bz - az*by
2004 axby = az*bx - ax*bz
2005 axbz = ax*by - ay*bx
2013 CLASS(timedisc_base) :: this
2015 IF (.NOT.this%Initialized()) &
2016 CALL this%Error(
"CloseTimedisc",
"not initialized")
2018 CALL this%Boundary%Finalize()
2020 CALL this%pvar%Destroy()
2021 CALL this%ptmp%Destroy()
2022 CALL this%cvar%Destroy()
2023 CALL this%ctmp%Destroy()
2024 CALL this%cold%Destroy()
2025 CALL this%geo_src%Destroy()
2026 CALL this%src%Destroy()
2027 CALL this%rhs%Destroy()
2030 this%pvar,this%cvar,this%ptmp,this%ctmp, &
2031 this%geo_src,this%src,this%rhs, &
2032 this%xfluxdydz,this%yfluxdzdx,this%zfluxdxdy,this%amax,this%tol_abs,&
2033 this%dtmean,this%dtstddev,this%time)
2035 IF (
ASSOCIATED(this%cerr))
THEN 2036 CALL this%cerr%Destroy()
2037 DEALLOCATE(this%cerr)
2039 IF (
ASSOCIATED(this%cerr_max))
THEN 2040 CALL this%cerr_max%Destroy()
2041 DEALLOCATE(this%cerr_max)
2043 IF (
ASSOCIATED(this%w))
DEALLOCATE(this%w)
2044 IF (
ASSOCIATED(this%delxy))
DEALLOCATE(this%delxy)
2045 IF (
ASSOCIATED(this%shift))
DEALLOCATE(this%shift)
2047 IF(
ASSOCIATED(this%buf))
DEALLOCATE(this%buf)
2049 IF(
ASSOCIATED(this%bflux))
DEALLOCATE(this%bflux)
2050 IF(
ASSOCIATED(this%solution))
THEN 2051 CALL this%solution%Destroy()
2052 DEALLOCATE(this%solution)
integer, parameter, public check_pmin
subroutine finalize(this)
Destructor of common class.
character(len=40), dimension(3), parameter fargo_method
integer, parameter, public check_all
generic source terms module providing functionaly common to all source terms
integer, parameter, public dtcause_cfl
integer, save default_mpi_real
default real type for MPI
subroutine finalize_base(this)
type(logging_base), save this
derived class for compound of mesh arrays
base class for mesh arrays
subroutine computerhs(this, Mesh, Physics, Sources, Fluxes, time, dt, pvar, cvar, checkdatabm, rhs)
compute the RHS of the spatially discretized PDE
defines properties of a 3D logcylindrical mesh
subroutine rejectsolution(this, Mesh, Physics, Sources, Fluxes, time, dt)
real function, dimension(mesh%igmin:mesh%igmax, mesh%jgmin:mesh%jgmax, mesh%kgmin:mesh%kgmax, physics%vdim) getcentrifugalvelocity(this, Mesh, Physics, Fluxes, Sources, dir_omega_, accel_, centrot)
Compute velocity leading to a centrifugal acceleration with respect to some given axis of rotation wh...
subroutine fargoadvectiony(this, Fluxes, Mesh, Physics, Sources)
Calculates the linear transport step in Fargo Scheme along y-axis .
defines properties of a 3D cylindrical mesh
subroutine fargoadvectionx(this, Fluxes, Mesh, Physics, Sources)
Calculates the linear transport step in Fargo Scheme along x-axis .
integer, parameter, public dtcause_fileio
smallest ts due to fileio
subroutine integrationstep(this, Mesh, Physics, Sources, Fluxes, iter, config, IO)
subroutine setoutput(this, Mesh, Physics, config, IO)
integer, parameter, public ssprk
pure real function getcfl(this)
generic gravity terms module providing functionaly common to all gravity terms
subroutine calcbackgroundvelocity(this, Mesh, Physics, pvar, cvar, w)
Calculates new background velocity for fargo advection.
real function computeerror(this, Mesh, Physics, cvar_high, cvar_low)
integer, parameter, public check_nothing
base module for reconstruction process
integer, parameter, public dtcause_smallerr
constructor for physics class
integer, parameter, public check_csound
integer, parameter, public check_tmin
physics module for 1D,2D and 3D isothermal Euler equations
subroutine acceptsolution(this, Mesh, Physics, Sources, Fluxes, time, dt, iter)
integer, parameter, public dtcause_erradj
named integer constants for flavour of state vectors
defines properties of a 3D cartesian mesh
subroutine checkdata(this, Mesh, Physics, Fluxes, pvar, cvar, checkdatabm)
compute the RHS of the spatially discretized PDE
integer, parameter, public modified_euler
elemental subroutine cross_product(ax, ay, az, bx, by, bz, aXbx, aXby, aXbz)
integer, parameter, public check_invalid
Dictionary for generic data types.
pure integer function getorder(this)
physics module for 1D,2D and 3D non-isothermal Euler equations
real function adjusttimestep(this, maxerr, dtold)
adjust the time step
integer, parameter, public rk_fehlberg
real function calctimestep(this, Mesh, Physics, Sources, Fluxes, time, dtcause)
Determines the CFL time step and time step limits due to source terms.
integer, parameter, public dormand_prince
base module for numerical flux functions
integer, parameter, public cash_karp
subroutine inittimedisc(this, Mesh, Physics, config, IO, ttype, tname)
integer, parameter, public check_rhomin