riemann1d.f90
Go to the documentation of this file.
1 !#############################################################################
2 !# #
3 !# fosite - 3D hydrodynamical simulation program #
4 !# module: riemann1d.f90 #
5 !# #
6 !# Copyright (C) 2006-2018 #
7 !# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8 !# #
9 !# This program is free software; you can redistribute it and/or modify #
10 !# it under the terms of the GNU General Public License as published by #
11 !# the Free Software Foundation; either version 2 of the License, or (at #
12 !# your option) any later version. #
13 !# #
14 !# This program is distributed in the hope that it will be useful, but #
15 !# WITHOUT ANY WARRANTY; without even the implied warranty of #
16 !# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or #
17 !# NON INFRINGEMENT. See the GNU General Public License for more #
18 !# details. #
19 !# #
20 !# You should have received a copy of the GNU General Public License #
21 !# along with this program; if not, write to the Free Software #
22 !# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
23 !# #
24 !#############################################################################
25 
26 !----------------------------------------------------------------------------!
53 !----------------------------------------------------------------------------!
54 PROGRAM riemann1d
55  USE fosite_mod
56  USE solutions
57 #include "tap.h"
58  IMPLICIT NONE
59  !--------------------------------------------------------------------------!
60  INTEGER, PARAMETER :: testnum = 8 ! number of available tests (do not modify)
61  CHARACTER(LEN=32), PARAMETER :: teststr(testnum) = (/ &
62  "Sod shock tube ", &
63  "Toro test no. 2 ", &
64  "Toro test no. 3 ", &
65  "Toro test no. 4 ", &
66  "Toro test no. 5 ", &
67  "Noh problem ", &
68  "Isothermal shock tube ", &
69  "Isothermal Noh problem " /)
70  !--------------------------------------------------------------------------!
71  ! mesh settings
72  CHARACTER(LEN=3), PARAMETER :: testdir = "all" ! direction: x,y,z or all
73  INTEGER, PARAMETER :: res = 400 ! resolution
74  ! output parameters
75  INTEGER, PARAMETER :: onum = 1 ! number of output data sets
76  CHARACTER(LEN=8), PARAMETER :: ofname(testnum) = (/ & ! output file name
77  "sod ","toro2 ","toro3 ","toro4 ","toro5 ","noh ", &
78  "sodiso ","noiso " /)
79  CHARACTER(LEN=256), PARAMETER & ! output data dir
80  :: odir = './'
81  ! some global constants
82  REAL :: gamma ! ratio of specific heats
83  REAL :: tsim ! simulation time
84  REAL :: csiso = 0.0 ! isothermal sound speed (test no. 6)
85  !--------------------------------------------------------------------------!
86  CLASS(fosite), ALLOCATABLE :: sim
87  CLASS(marray_compound), POINTER :: pvar_exact
88  CHARACTER(LEN=64) :: verbose_tap_output
89  INTEGER :: ic,sd,dir_min,dir_max
90  REAL, DIMENSION(:,:), ALLOCATABLE :: sigma
91  REAL, PARAMETER :: sigma_tol(testnum) &
92  = (/ 1.8e-2, 1.4e-2, 7.9e+0, 3.5e+1, 4.3e+0, 7.9e-2, 1.0e+0, 1.0e+0 /)
93  !--------------------------------------------------------------------------!
94 
95  ! check whether we perform tests in all directions
96  SELECT CASE (trim(testdir))
97  CASE("all")
98  dir_min = 1
99  dir_max = 3
100  CASE("y")
101  dir_min = 2
102  dir_max = 2
103  CASE("z")
104  dir_min = 3
105  dir_max = 3
106  CASE DEFAULT
107  ! x-direction is also the default
108  dir_min = 1
109  dir_max = 1
110  END SELECT
111 
112  tap_plan(testnum*(dir_max-dir_min+1))
113 
114  ALLOCATE(sigma(testnum,dir_min:dir_max))
115  ! loop over all tests
116  DO ic=1,testnum
117  ! loop over selected directions
118  DO sd=dir_min,dir_max
119 
120  ! initialize Fosite
121  ALLOCATE(sim)
122  CALL sim%InitFosite()
123 
124  ! get configuration for the particular test and direction
125  CALL makeconfig(sim, sim%config,ic,sd)
126 ! CALL PrintDict(config)
127 
128  ! setup the simulation
129  CALL sim%Setup()
130 
131  ! create state vector for exact solution
132  CALL sim%Physics%new_statevector(pvar_exact,primitive)
133 
134  ! set initial conditions and run the simulation
135  CALL run(sim,pvar_exact,ic,sd)
136 
137  IF (sim%aborted) THEN
138  sigma(ic,sd) = huge(1.0)
139  ELSE
140  IF (ASSOCIATED(sim%Timedisc%solution)) THEN
141  sigma(ic,sd) = sqrt(sum((sim%Timedisc%pvar%data1d(:) &
142  -sim%Timedisc%solution%data1d(:))**2)/SIZE(sim%Timedisc%pvar%data1d))
143  ELSE
144  sigma(ic,sd) = 0.0
145  END IF
146  END IF
147 
148  CALL pvar_exact%Destroy()
149  CALL sim%Finalize()
150  DEALLOCATE(sim)
151 
152  END DO
153  END DO
154 
155  ! check results
156  ! loop over all tests
157  DO ic=1,testnum
158  ! loop over selected directions
159  DO sd=dir_min,dir_max
160  WRITE (verbose_tap_output,'(A,ES8.2)') trim(teststr(ic)) // " / " // achar(119+sd) &
161  // " sigma = ", sigma(ic,sd)
162 ! This line is long if expanded. So we can't indent it or it will be cropped.
163 tap_check_small(sigma(ic,sd),sigma_tol(ic),trim(verbose_tap_output))
164  END DO
165  END DO
166 
167 tap_done
168 
169 CONTAINS
170 
171  SUBROUTINE makeconfig(Sim,config,ic,dir)
172  IMPLICIT NONE
173  !------------------------------------------------------------------------!
174  CLASS(Fosite) :: Sim
175  TYPE(Dict_TYP),POINTER :: config
176  INTEGER :: ic,dir
177  !------------------------------------------------------------------------!
178  ! Local variable declaration
179  TYPE(Dict_TYP), POINTER :: mesh, physics, boundary, datafile, &
180  timedisc, fluxes
181  INTEGER :: xres,yres,zres
182  REAL :: xmax,ymax,zmax
183  !------------------------------------------------------------------------!
184  INTENT(INOUT) :: sim
185  INTENT(IN) :: ic,dir
186  !------------------------------------------------------------------------!
187  ! mesh settings depends on the direction selected above
188  SELECT CASE(dir)
189  CASE(1)
190  xmax = 1.0
191  ymax = 0.0
192  zmax = 0.0
193  xres = res
194  yres = 1
195  zres = 1
196  CASE(2)
197  xmax = 0.0
198  ymax = 1.0
199  zmax = 0.0
200  xres = 1
201  yres = res
202  zres = 1
203  CASE(3)
204  xmax = 0.0
205  ymax = 0.0
206  zmax = 1.0
207  xres = 1
208  yres = 1
209  zres = res
210  CASE DEFAULT
211  CALL sim%Error("riemann1d::InitData","direction must be one of 1,2,3")
212  END SELECT
213 
214  ! mesh settings
215  mesh => dict("meshtype" / midpoint, &
216  "geometry" / cartesian, &
217  "inum" / xres, & ! resolution in x and !
218  "jnum" / yres, & ! y direction !
219  "knum" / zres, & ! z direction !
220  "xmin" / (0.0), &
221  "xmax" / xmax, &
222  "ymin" / (-0.0), &
223  "ymax" / ymax, &
224  "zmin" / (0.0), &
225  "zmax" / zmax &
226  )
227 
228  SELECT CASE(ic)
229  CASE(1)
230  gamma = 1.4
231  tsim = 0.25
232  CASE(2)
233  gamma = 1.4
234  tsim = 0.15
235  CASE(3)
236  gamma = 1.4
237  tsim = 0.012
238  CASE(4)
239  gamma = 1.4
240  tsim = 0.035
241  CASE(5)
242  gamma = 1.4
243  tsim = 0.012
244  CASE(6)
245  gamma = 5./3.
246  tsim = 1.0
247  CASE(7)
248  csiso = 1.0
249  tsim = 0.25
250  CASE(8)
251  csiso = 1.0
252  tsim = 0.5
253  CASE DEFAULT
254  CALL sim%Mesh%Error("riemann1d::InitData", "Test problem number should be 1,2,3,4,5,6,7 or 8")
255  END SELECT
256 
257 
258  ! physics settings
259  IF (csiso.NE.0.0) THEN
260  physics => dict("problem" / euler_isotherm, &
261  "cs" / csiso)
262  ELSE
263  physics => dict("problem" / euler, &
264  "gamma" / gamma) ! ratio of specific heats !
265  END IF
266 
267  ! flux calculation and reconstruction method
268  fluxes => dict(&
269  "fluxtype" / kt, &
270  "order" / linear, &
271  "variables" / conservative, & ! vars. to use for reconstruction!
272  "limiter" / monocent, & ! one of: minmod, monocent,... !
273  "theta" / 1.2 & ! optional parameter for limiter !
274  )
275  ! time discretization settings
276  timedisc => dict( &
277  "method" / modified_euler, &
278  "order" / 3, &
279  "cfl" / 0.4, &
280  "stoptime" / tsim, &
281  "dtlimit" / 1.0e-10, &
282 ! "output/xmomentum" / 1, &
283 ! "output/ymomentum" / 1, &
284 ! "output/zmomentum" / 1, &
285 ! "output/energy" / 1, &
286 ! "output/rhs" / 1 &
287  "output/solution" / 0, &
288  "maxiter" / 100000 &
289  )
290 
291  ! compute and output exact solution in non-isothermal simulations
292  IF (csiso.EQ.0.0) CALL setattr(timedisc,"output/solution",1)
293 
294  ! boundary conditions
295  boundary => dict( &
296  "western" / no_gradients, &
297  "eastern" / no_gradients, &
298  "southern" / no_gradients, &
299  "northern" / no_gradients, &
300  "bottomer" / no_gradients, &
301  "topper" / no_gradients)
302 
303  ! initialize data input/output
304  datafile => dict( &
305  "fileformat" / vtk, &
306  "filename" / (trim(odir) // trim(ofname(ic)) // "-" // achar(119+dir)), &
307 ! "filecycles" / 0, &
308  "count" / onum)
309 
310  config => dict("mesh" / mesh, &
311  "physics" / physics, &
312  "boundary" / boundary, &
313  "fluxes" / fluxes, &
314  "timedisc" / timedisc, &
315  "datafile" / datafile)
316  END SUBROUTINE makeconfig
317 
318  SUBROUTINE run(this,pvar,ic,dir)
320  IMPLICIT NONE
321  !------------------------------------------------------------------------!
322  CLASS(fosite), INTENT(INOUT) :: this
323  CLASS(marray_compound), POINTER :: pvar
324  INTEGER, INTENT(IN) :: ic,dir
325  !------------------------------------------------------------------------!
326  ! Local variable declaration
327  REAL :: x0, rho_l, rho_r, u_l, u_r, p_l, p_r
328  REAL, DIMENSION(:), ALLOCATABLE :: x
329  !------------------------------------------------------------------------!
330 
331  SELECT CASE(ic)
332  CASE(1) ! Sod shock tube (Toro's test no. 1)
333  x0 = 0.5
334  rho_l = 1.0
335  rho_r = 0.125
336  u_l = 0.0
337  u_r = 0.0
338  p_l = 1.0
339  p_r = 0.1
340  CASE(2) ! Toro's test no. 2
341  x0 = 0.5
342  rho_l = 1.0
343  rho_r = 1.0
344  u_l = -2.0
345  u_r = 2.0
346  p_l = 0.4
347  p_r = 0.4
348  CASE(3) ! Toro's test no. 3
349  x0 = 0.5
350  rho_l = 1.0
351  rho_r = 1.0
352  u_l = 0.0
353  u_r = 0.0
354  p_l = 1000.
355  p_r = 0.01
356  CASE(4) ! Toro's test no. 4
357  x0 = 0.4
358  rho_l = 5.99924
359  rho_r = 5.99924
360  u_l = 19.5975
361  u_r = -6.19633
362  p_l = 460.894
363  p_r = 46.0950
364  CASE(5) ! Toro's test no. 5
365  x0 = 0.8
366  rho_l = 1.0
367  rho_r = 1.0
368  u_l = -19.5975
369  u_r = -19.5975
370  p_l = 1000.0
371  p_r = 0.01
372  CASE(6) ! Noh problem
373  x0 = 0.5
374  rho_l = 1.0
375  rho_r = 1.0
376  u_l = 1.0
377  u_r = -1.0
378  p_l = 1.0e-05
379  p_r = 1.0e-05
380  CASE(7) ! isothermal shock tube
381  x0 = 0.5
382  rho_l = 1.0
383  rho_r = 0.125
384  u_l = 0.0
385  u_r = 0.0
386  CASE(8) ! isothermal Noh problem
387  x0 = 0.5
388  rho_l = 1.0
389  rho_r = 1.0
390  u_l = 1.0
391  u_r = -1.0
392  CASE DEFAULT
393  CALL this%Error("InitData", "Test problem should be 1,2,3,4,5,6,7 or 8")
394  END SELECT
395 
396  ! initial condition
397  ! always set density and first velocity
398  SELECT TYPE(pvar => this%Timedisc%pvar)
399  CLASS IS(statevector_eulerisotherm)
400  ! set all velocities to 0
401  pvar%velocity%data1d(:) = 0.0
402  WHERE (this%Mesh%bcenter(:,:,:,dir).LT.x0)
403  pvar%density%data3d(:,:,:) = rho_l
404  pvar%velocity%data4d(:,:,:,1) = u_l
405  ELSEWHERE
406  pvar%density%data3d(:,:,:) = rho_r
407  pvar%velocity%data4d(:,:,:,1) = u_r
408  END WHERE
409  END SELECT
410 
411  ! set pressure for non-isothermal HD
412  SELECT TYPE(pvar => this%Timedisc%pvar)
413  TYPE IS(statevector_euler)
414  WHERE (this%Mesh%bcenter(:,:,:,dir).LT.x0)
415  pvar%pressure%data3d(:,:,:) = p_l
416  ELSEWHERE
417  pvar%pressure%data3d(:,:,:) = p_r
418  END WHERE
419  END SELECT
420 
421  CALL this%Physics%Convert2Conservative(this%Timedisc%pvar,this%Timedisc%cvar)
422  CALL this%Info(" DATA-----> initial condition: " &
423  // "1D Riemann problem: " // trim(teststr(ic)))
424 
425  IF (ASSOCIATED(this%Timedisc%solution)) THEN
426  ! store initial condition in exact solution array
427  this%Timedisc%solution = this%Timedisc%pvar
428 
429  ! set 1D coordinate array for exact solution
430  ALLOCATE(x(SIZE(this%Mesh%cart%data3d(:,2,dir),1)), &
431  source=this%Mesh%cart%data3d(:,2,dir))
432 
433  DO WHILE((this%Timedisc%maxiter.LE.0).OR.(this%iter.LE.this%Timedisc%maxiter))
434  SELECT TYPE(phys => this%Physics)
435  TYPE IS (physics_euler)
436  ! compute exact solution of the 1D Riemann problem (only non-isothermal HD)
437  CALL riemann(x0,phys%gamma,rho_l,u_l,p_l,rho_r,u_r,p_r, &
438  this%Timedisc%time,x,this%Timedisc%solution%data2d(:,:))
439  END SELECT
440  IF(this%Step()) EXIT
441  END DO
442  ELSE
443  CALL this%Run()
444  END IF
445  END SUBROUTINE run
446 
447 END PROGRAM riemann1d
program riemann1d
1D Riemann problems
Definition: riemann1d.f90:54
main fosite class
Definition: fosite.f90:71
subroutine, private run(this)
Definition: fosite.f90:336
subroutine makeconfig(Sim, config)
Definition: bondi2d.f90:165
subroutine, public riemann(x0, gamma_, rho_l_, u_l_, p_l_, rho_r_, u_r_, p_r_, t, x, pvar)
Definition: solutions.f90:51
real gamma
Definition: solutions.f90:38