71 REAL,
DIMENSION(:),
POINTER :: b_low,b_high,c
72 REAL,
DIMENSION(:,:),
POINTER :: a
94 SUBROUTINE inittimedisc(this,Mesh,Physics,config,IO,ttype,tname)
99 CLASS(timedisc_rkfehlberg),
INTENT(INOUT) :: this
100 CLASS(mesh_base),
INTENT(INOUT) :: Mesh
101 CLASS(physics_base),
INTENT(IN) :: Physics
102 TYPE(Dict_TYP),
POINTER :: config,IO
103 INTEGER,
INTENT(IN) :: ttype
104 CHARACTER(LEN=32),
INTENT(IN) :: tname
106 INTEGER :: err,k,ShowBT
108 CALL this%timedisc_modeuler%InitTimedisc(mesh,physics,config,io,ttype,tname)
110 ALLOCATE(this%b_high(this%m),this%b_low(this%m),&
111 this%c(this%m),this%a(this%m,this%m), &
112 this%coeff(this%m), &
115 CALL this%Error(
"timedisc_rkfehlberg::InitTimedisc",
"Unable to allocate memory.")
119 CALL this%SetButcherTableau()
120 CALL getattr(config,
"ShowButcherTableau", showbt, 0)
121 IF (showbt.EQ.1)
CALL this%ShowButcherTableau()
124 this%coeff(1)%p => this%rhs
126 CALL physics%new_statevector(this%coeff(k)%p,conservative)
127 this%coeff(k)%p%data1d(:) = 0.0
130 IF ((this%tol_rel.LT.0.0).OR.minval(this%tol_abs(:)).LT.0.0) &
131 CALL this%Error(
"timedisc_rkfehlberg::InitTimedisc", &
132 "error tolerance levels must be greater than 0")
134 IF (this%tol_rel.GT.1.0)
THEN 135 CALL this%Warning(
"timedisc_rkfehlberg::InitTimedisc", &
136 "adaptive step size control disabled (tol_rel>1)",0)
137 ELSE IF(this%tol_rel.GE.0.01 .AND. this%order .GE. 5)
THEN 138 CALL this%Warning(
"timedisc_rkfehlberg::InitTimedisc", &
139 "You chose a relatively high tol_rel (in comparison to order)",0)
147 CLASS(Timedisc_rkfehlberg),
INTENT(INOUT) :: this
148 CLASS(Mesh_base),
INTENT(INOUT) :: Mesh
149 CLASS(Physics_base),
INTENT(IN) :: Physics
150 TYPE(Dict_TYP),
POINTER :: config,IO
153 CALL getattr(config,
"order", this%order, 5)
156 SELECT CASE(this%GetOrder())
162 CALL this%Error(
"InitTimedisc_rkfehlberg",
"time order must be 3 or 5")
169 SUBROUTINE solveode(this,Mesh,Physics,Sources,Fluxes,time,dt,err)
172 CLASS(Timedisc_rkfehlberg),
INTENT(INOUT) :: this
173 CLASS(Mesh_base),
INTENT(IN) :: Mesh
174 CLASS(Physics_base),
INTENT(INOUT) :: Physics
175 CLASS(Fluxes_base),
INTENT(INOUT) :: Fluxes
176 CLASS(sources_base),
POINTER :: Sources
177 REAL,
INTENT(IN) :: time
178 REAL,
INTENT(INOUT) :: dt,err
192 CALL this%ComputeCVar_rkfehlberg(mesh,physics,fluxes,dt,m,this%coeff,this%cvar,this%ctmp)
195 CALL this%ComputeRHS(mesh,physics,sources,fluxes,t+this%c(m)*dt,dt,&
200 this%ctmp = this%cvar
205 this%ctmp%data1d(:) = this%ctmp%data1d(:) &
206 - this%b_low(m)*dt*this%coeff(m)%p%data1d(:)
207 this%cvar%data1d(:) = this%cvar%data1d(:) &
208 - this%b_high(m)*dt*this%coeff(m)%p%data1d(:)
217 IF(mesh%INUM.GT.1)
THEN 220 DO k=mesh%KMIN,mesh%KMAX
222 DO j=mesh%JMIN,mesh%JMAX
223 fluxes%bxflux(j,k,1,l) = fluxes%bxflux(j,k,1,l) &
224 - dt*this%b_high(m)*this%coeff(m)%p%data4d(mesh%IMIN-mesh%IP1,j,k,l)
225 fluxes%bxflux(j,k,2,l) = fluxes%bxflux(j,k,2,l) &
226 - dt*this%b_high(m)*this%coeff(m)%p%data4d(mesh%IMAX+mesh%IP1,j,k,l)
231 IF(mesh%JNUM.GT.1)
THEN 233 DO k=mesh%KMIN,mesh%KMAX
235 DO i=mesh%IMIN,mesh%IMAX
236 fluxes%byflux(k,i,1,l) = fluxes%byflux(k,i,1,l) &
237 - dt*this%b_high(m)*this%coeff(m)%p%data4d(i,mesh%JMIN-mesh%JP1,k,l)
238 fluxes%byflux(k,i,2,l) = fluxes%byflux(k,i,2,l) &
239 - dt*this%b_high(m)*this%coeff(m)%p%data4d(i,mesh%JMAX+mesh%JP1,k,l)
244 IF(mesh%KNUM.GT.1)
THEN 246 DO j=mesh%JMIN,mesh%JMAX
248 DO i=mesh%IMIN,mesh%IMAX
249 fluxes%bzflux(i,j,1,l) = fluxes%bzflux(i,j,1,l) &
250 - dt*this%b_high(m)*this%coeff(m)%p%data4d(i,j,mesh%KMIN-mesh%KP1,l)
251 fluxes%bzflux(i,j,2,l) = fluxes%bzflux(i,j,2,l) &
252 - dt*this%b_high(m)*this%coeff(m)%p%data4d(i,j,mesh%KMAX+mesh%KP1,l)
261 IF (this%tol_rel.LE.1.0)
THEN 262 err = this%ComputeError(mesh,physics,this%cvar,this%ctmp)
263 dt = this%AdjustTimestep(err,dt)
278 CLASS(Timedisc_rkfehlberg),
INTENT(INOUT) :: this
279 CLASS(Mesh_base) ,
INTENT(IN) :: Mesh
280 CLASS(Physics_base) ,
INTENT(INOUT) :: Physics
281 CLASS(Fluxes_base) ,
INTENT(INOUT) :: Fluxes
282 REAL ,
INTENT(IN) :: dt
283 INTEGER ,
INTENT(IN) :: m
284 TYPE(coeff_type),
DIMENSION(m),
INTENT(IN) :: coeff
285 CLASS(marray_compound) ,
INTENT(INOUT) :: cvar,cnew
294 cnew%data1d(:) = cvar%data1d(:) - this%a(m,1)*dt*coeff(1)%p%data1d(:)
297 cnew%data1d(:) = cnew%data1d(:) - this%a(m,mm)*dt*coeff(mm)%p%data1d(:)
306 CLASS(timedisc_rkfehlberg) :: this
308 SELECT CASE(this%GetOrder())
310 this%b_high = (/ 1.0/6.0, 2.0/3.0, 1.0/6.0 /)
311 this%b_low = (/ 0.0, 1.0, 0.0 /)
312 this%c = (/ 0.0, 0.5, 1.0 /)
313 this%a = transpose(reshape((/ &
316 -1.0, 2.0, 0.0 /),(/this%m,this%m/)))
318 this%b_high = (/ 16.0/135.0, 0.0, 6656.0/12825.0, &
319 28561.0/56430.0, -9.0/50.0, 2.0/55.0 /)
320 this%b_low = (/ 25.0/216.0, 0.0, 1408.0/2565.0, 2197.0/4104.0, -0.2, 0.0 /)
321 this%c = (/ 0.0, 0.25, 3.0/8.0, 12.0/13.0, 1.0, 0.5 /)
322 this%a = transpose(reshape((/ &
323 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, &
324 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, &
325 3.0/32.0, 9.0/32.0, 0.0, 0.0, 0.0, 0.0, &
326 1932.0/2197.0, -7200.0/2197.0, 7296.0/2197.0, 0.0, 0.0, 0.0, &
327 439.0/216.0, -8.0, 3680.0/513.0, -845.0/4104.0, 0.0, 0.0, &
328 -8.0/27.0, 2.0, -3544.0/2565.0, 1859.0/4104.0, -11.0/40.0, 0.0/),&
331 CALL this%Error(
"timedisc_rkfehlberg::SetButcherTableau",
"only order 3 or 5 supported")
339 CLASS(Timedisc_rkfehlberg) :: this
342 CHARACTER(LEN=64) :: sformat
343 CHARACTER(LEN=128) :: buffer
345 INTENT(INOUT) :: this
347 CALL this%Info(repeat(
"+",(this%m+1)*12+4))
348 CALL this%Info(
"Butcher tableau")
351 WRITE (sformat,
'(A)')
'(ES12.3,A)' 353 WRITE (sformat,
'(A,I1,A)')
'(ES12.3,A,',i-1,
'ES12.3)' 355 WRITE (buffer,fmt=sformat) this%c(i),
" | " , this%a(i,1:i-1)
356 CALL this%Info(buffer)
358 CALL this%Info(repeat(
"-",(this%m+1)*12+4))
359 WRITE (sformat,
'(A,I1,A)')
'(A,',this%m,
'ES12.3)' 360 WRITE (buffer,fmt=sformat)
" high order | ", this%b_high(:)
361 CALL this%Info(buffer)
362 WRITE (buffer,fmt=sformat)
" low order | ", this%b_low(:)
363 CALL this%Info(buffer)
364 CALL this%Info(repeat(
"+",(this%m+1)*12+4))
365 WRITE (buffer,fmt=sformat)
"c_i-SUM(a_ij)| ", this%c(:)-sum(this%a(:,:),dim=2)
366 CALL this%Info(buffer)
373 CLASS(Timedisc_rkfehlberg) :: this
377 DEALLOCATE(this%b_high,this%b_low,this%c,this%a)
379 CALL this%coeff(k)%p%Destroy()
380 DEALLOCATE(this%coeff(k)%p)
382 DEALLOCATE(this%coeff)
383 CALL this%timedisc_modeuler%Finalize()
character(len=32), parameter odesolver_name
generic source terms module providing functionaly common to all source terms
derived class for compound of mesh arrays
base class for mesh arrays
subroutine solveode(this, Mesh, Physics, Sources, Fluxes, time, dt, err)
integer, parameter, public check_nothing
subroutine finalize(this)
physics module for 1D,2D and 3D isothermal Euler equations
subroutine setbutchertableau(this)
set coefficients for RK-Fehlberg schemes
Dictionary for generic data types.
physics module for 1D,2D and 3D non-isothermal Euler equations
subroutine showbutchertableau(this)
integer, parameter, public rk_fehlberg
subroutines for Runge-Kutta Fehlberg method
subroutines for modified Euler i.e. Runge-Kutta methods
base module for numerical flux functions
subroutine inittimedisc(this, Mesh, Physics, config, IO, ttype, tname)
subroutine computecvar_rkfehlberg(this, Mesh, Physics, Fluxes, dt, m, coeff, cvar, cnew)
perfroms the time step update using the RHS
subroutine inittimedisc_rkfehlberg(this, Mesh, Physics, config, IO)