sedov3d.f90
Go to the documentation of this file.
1 !#############################################################################
2 !# #
3 !# fosite - 3D hydrodynamical simulation program #
4 !# module: sedov3d.f90 #
5 !# #
6 !# Copyright (C) 2006-2014 #
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 !----------------------------------------------------------------------------!
34 !----------------------------------------------------------------------------!
35 PROGRAM sedov3d
36  USE fosite_mod
37  USE solutions
38 #include "tap.h"
39  IMPLICIT NONE
40  !--------------------------------------------------------------------------!
41  ! simulation parameters
42  REAL, PARAMETER :: tsim = 0.05 ! simulation stop time
43  REAL, PARAMETER :: gamma = 1.4 ! ratio of specific heats
44  REAL, PARAMETER :: r = 1.033 ! scaling parameter: 1.0 for 2D, 1.033 for 3D
45  ! initial condition (dimensionless units)
46  REAL, PARAMETER :: rho0 = 1.0 ! ambient density
47  REAL, PARAMETER :: p0 = 1.0e-05 ! ambient pressure
48  REAL, PARAMETER :: e1 = 1.0 ! initial energy input
49  ! Spatial with of the initial pulse should be at least 5 cells;
50  ! if you wish to compare the results on different grids
51  ! R0 should be of the same order
52  REAL, PARAMETER :: r0 = 5.0e-2
53  ! mesh settings
54 ! INTEGER, PARAMETER :: MGEO = LOGSPHERICAL ! geometry
55  INTEGER, PARAMETER :: mgeo = spherical ! geometry
56 ! INTEGER, PARAMETER :: MGEO = CARTESIAN ! geometry
57  INTEGER, PARAMETER :: xres = 50 ! x-resolution
58  INTEGER, PARAMETER :: yres = 2 ! y-resolution
59  INTEGER, PARAMETER :: zres = 2 ! z-resolution
60  REAL, PARAMETER :: rmax = 0.4 ! outer radius of comput. domain
61  REAL, PARAMETER :: gpar = 0.2 ! geometry scaling parameter
62  ! output parameters
63  INTEGER, PARAMETER :: onum = 10 ! number of output data sets
64  CHARACTER(LEN=256), PARAMETER & ! output data dir
65  :: odir = './'
66  CHARACTER(LEN=256), PARAMETER & ! output data file name
67  :: ofname = 'sedov3d'
68  !-------------------------------------------------------------------------!
69  CLASS(fosite), ALLOCATABLE :: sim
70  !-------------------------------------------------------------------------!
71  REAL, DIMENSION(:),ALLOCATABLE :: pvar_diff
72 #ifdef PARALLEL
73  REAL, DIMENSION(:), POINTER :: pvar,pvar_all,radius,radius_all
74  INTEGER :: err
75 #endif
76  INTEGER :: i
77  REAL :: rt,rshock
78  !-------------------------------------------------------------------------!
79  ALLOCATE(sim,pvar_diff(1:xres))
80  CALL sim%InitFosite()
81 #ifdef PARALLEL
82  IF(sim%GetRank().EQ.0) &
83 #endif
84  tap_plan(1)
85 
86  CALL makeconfig(sim, sim%config)
87  CALL sim%Setup()
88  CALL initdata(sim%Mesh, sim%Physics, sim%Timedisc)
89 
90  CALL sim%Run()
91 
92 #ifdef PARALLEL
93  ALLOCATE(pvar(sim%Mesh%IMIN:sim%Mesh%IMAX),pvar_all(sim%GetNumProcs()*(sim%Mesh%IMAX-sim%Mesh%IMIN+1)))
94  ALLOCATE(radius(sim%Mesh%IMIN:sim%Mesh%IMAX),radius_all(sim%GetNumProcs()*(sim%Mesh%IMAX-sim%Mesh%IMIN+1)))
95  pvar(:) = sim%Timedisc%pvar%data4d(sim%Mesh%IMIN:sim%Mesh%IMAX,1,1,1)
96  radius(:)= sim%Mesh%radius%center(sim%Mesh%IMIN:sim%Mesh%IMAX,1,1)
97 
98  ! Compare results with analytical solution. Check only for correct shock velocity
99  ! even if the full analytical solution is implemented
100 
101 ! CALL sedov(GAMMA,E1,RHO0,P0,TSIM,3, SIM%Mesh%radius%bcenter(1:XRES,1,1),pvar)
102 
103  !The shock location is where the density gradient is greatest
104  CALL mpi_gather(pvar,int(sim%Mesh%IMAX-sim%Mesh%IMIN+1),mpi_double, &
105  pvar_all, int(sim%Mesh%IMAX-sim%Mesh%IMIN+1),mpi_double,0,mpi_comm_world,err)
106  CALL mpi_gather(radius,int(sim%Mesh%IMAX-sim%Mesh%IMIN+1),mpi_double, &
107  radius_all, int(sim%Mesh%IMAX-sim%Mesh%IMIN+1),mpi_double,0,mpi_comm_world,err)
108 
109  IF(sim%GetRank().EQ.0) THEN
110  DO i=1,xres-1
111  pvar_diff(i) = pvar_all(i)-pvar_all(i+1)
112  END DO
113  rshock = radius_all(maxloc(pvar_diff,dim=1))
114 
115  !analytical shock position
116  rt = r*(e1*tsim**2/rho0)**0.2
117 
118  !Check whether analytical solution is within +/- one cell of simulated shock
119  tap_check((rt.LT.rshock+sim%Mesh%dx).AND.(rt.GT.rshock-sim%Mesh%dx),"Shock velocity correct")
120 END IF
121 #else
122  DO i=1,xres
123  pvar_diff(i) = sim%Timedisc%pvar%data4d(i,1,1,1)-sim%Timedisc%pvar%data4d(i+1,1,1,1)
124  END DO
125  rshock = sim%Mesh%radius%center(maxloc(pvar_diff,dim=1),1,1)
126 
127  !analytical shock position
128  rt = r*(e1*tsim**2/rho0)**0.2
129 
130  tap_check((rt.LT.rshock+sim%Mesh%dx).AND.(rt.GT.rshock-sim%Mesh%dx),"Shock velocity correct")
131 #endif
132  CALL sim%Finalize()
133  tap_done
134  DEALLOCATE(sim,pvar_diff)
135 
136 CONTAINS
137 
138  SUBROUTINE makeconfig(Sim, config)
139  USE functions, ONLY : asinh,acosh
140  IMPLICIT NONE
141  !------------------------------------------------------------------------!
142  CLASS(fosite) :: Sim
143  TYPE(Dict_TYP),POINTER :: config
144  !------------------------------------------------------------------------!
145  ! Local variable declaration
146  INTEGER :: bc(6)
147  TYPE(Dict_TYP), POINTER :: mesh, physics, boundary, datafile, &
148  timedisc, fluxes
149  REAL :: x1,x2,y1,y2,z1,z2
150  !------------------------------------------------------------------------!
151  INTENT(INOUT) :: sim
152  !------------------------------------------------------------------------!
153  ! mesh settings and boundary conditions
154  SELECT CASE(mgeo)
155  CASE(cartesian)
156  x1 = -0.5
157  x2 = 0.5
158  y1 = -0.5
159  y2 = 0.5
160  z1 = -0.5
161  z2 = 0.5
162  bc(west) = no_gradients
163  bc(east) = no_gradients
164  bc(south) = no_gradients
165  bc(north) = no_gradients
166  bc(bottom)= no_gradients
167  bc(top) = no_gradients
168  CASE(spherical)
169  x1 = 0.0
170  x2 = rmax
171  y1 = 0.0
172  y2 = pi
173  z1 = 0.0
174  z2 = 2*pi
175  bc(west) = reflecting
176  bc(east) = no_gradients
177  bc(south) = axis
178  bc(north) = axis
179  bc(bottom)= periodic
180  bc(top) = periodic
181  CASE(logspherical)
182  x1 = log(1e-3/gpar)
183  x2 = log(rmax/gpar)
184  y1 = 0.0
185  y2 = pi
186  z1 = 0.0
187  z2 = 2*pi
188  bc(west) = reflecting
189  bc(east) = no_gradients
190  bc(south) = axis
191  bc(north) = axis
192  bc(bottom)= periodic
193  bc(top) = periodic
194  CASE(cylindrical)
195  x1 = -rmax
196  x2 = rmax
197  y1 = 0.0
198  y2 = 2.0*pi
199  z1 = 0.0
200  z2 = rmax
201  bc(west) = no_gradients !default: ABSORBING
202  bc(east) = no_gradients !default: ABSORBING
203  bc(south) = no_gradients !default: AXIS
204  bc(north) = no_gradients !default: ABSORBING
205  bc(bottom)= no_gradients
206  bc(top) = no_gradients
207 ! CASE(OBLATE_SPHEROIDAL) !TODO anderen Meshs zu 3D konvertieren
208 ! x1 = 0.0
209 ! x2 = Acosh(RMAX/GPAR)
210 ! y1 = -0.5*PI
211 ! y2 = 0.5*PI
212 ! bc(WEST) = FOLDED
213 ! bc(EAST) = NO_GRADIENTS
214 ! bc(SOUTH) = AXIS
215 ! bc(NORTH) = AXIS
216 ! CASE(TANCYLINDRICAL)
217 ! x1 = ATAN(-RMAX/GPAR)
218 ! x2 = ATAN(RMAX/GPAR)
219 ! y1 = 0.0
220 ! y2 = RMAX
221 ! bc(WEST) = NO_GRADIENTS
222 ! bc(EAST) = NO_GRADIENTS
223 ! bc(SOUTH) = AXIS
224 ! bc(NORTH) = NO_GRADIENTS
225 ! CASE(SINHSPHERICAL)
226 ! x1 = 0.0
227 ! x2 = Asinh(RMAX/GPAR)
228 ! y1 = 0.0
229 ! y2 = PI
230 ! bc(WEST) = REFLECTING
231 ! bc(EAST) = NO_GRADIENTS
232 ! bc(SOUTH) = AXIS
233 ! bc(NORTH) = AXIS
234  CASE DEFAULT
235  CALL sim%Physics%Error("InitProgram","geometry not supported for 3D Sedov explosion")
236  END SELECT
237 
238  ! mesh settings
239  mesh => dict( &
240  "meshtype" / midpoint, &
241  "geometry" / mgeo, &
242  "inum" / xres, &
243  "jnum" / yres, &
244  "knum" / zres, &
245  "xmin" / x1, &
246  "xmax" / x2, &
247  "ymin" / y1, &
248  "ymax" / y2, &
249  "zmin" / z1, &
250  "zmax" / z2, &
251  "gparam" / gpar )
252 
253  ! boundary conditions
254  boundary => dict( &
255  "western" / bc(west), &
256  "eastern" / bc(east), &
257  "southern" / bc(south), &
258  "northern" / bc(north), &
259  "bottomer" / bc(bottom), &
260  "topper" / bc(top))
261 
262  ! physics settings
263  physics => dict( &
264  "problem" / euler, &
265  "gamma" / gamma)
266 
267  ! flux calculation and reconstruction method
268  fluxes => dict( &
269  "order" / linear, &
270  "fluxtype" / kt, &
271  "variables" / primitive, &
272  "limiter" / superbee)
273 
274  ! time discretization settings
275  timedisc => dict( &
276  "method" / dormand_prince, &
277  "order" / 5, &
278  "cfl" / 0.4, &
279  "stoptime" / tsim, &
280  "dtlimit" / 1.0e-13, &
281  "tol_rel" / 0.01, &
282  "tol_abs" / (/1e-5,1e-5,1e-5,1e-5,1e-5/), &
283  "maxiter" / 1000000 )
284 
285  ! initialize data input/output
286  datafile => dict( &
287  "fileformat" / vtk, &
288  "filename" / (trim(odir) // trim(ofname)), &
289  "count" / onum)
290 
291  config => dict( &
292  "mesh" / mesh, &
293  "physics" / physics, &
294  "boundary" / boundary, &
295  "fluxes" / fluxes, &
296  "timedisc" / timedisc, &
297  "datafile" / datafile )
298  END SUBROUTINE makeconfig
299 
300  SUBROUTINE initdata(Mesh,Physics,Timedisc)
302  IMPLICIT NONE
303  !------------------------------------------------------------------------!
304  CLASS(physics_base), INTENT(IN) :: Physics
305  CLASS(mesh_base), INTENT(IN) :: Mesh
306  CLASS(timedisc_base), INTENT(INOUT) :: Timedisc
307  !------------------------------------------------------------------------!
308  ! Local variable declaration
309  INTEGER :: n
310  REAL :: P1
311  !------------------------------------------------------------------------!
312  ! isothermal modules are excluded
313  SELECT TYPE (phys => physics)
314  CLASS IS(physics_euler)
315  ! peak pressure
316  n = 3 ! 3 for 3D
317  p1 = 3.*(phys%gamma - 1.0)*e1 / ((n + 1)*pi*r0**n)
318  CLASS DEFAULT
319  ! abort
320  CALL phys%Error("InitData","physics not supported")
321  END SELECT
322 
323  ! uniform density
324  timedisc%pvar%data4d(:,:,:,physics%DENSITY) = rho0
325  ! vanishing initial velocities
326  timedisc%pvar%data4d(:,:,:,physics%XVELOCITY) = 0.
327  timedisc%pvar%data4d(:,:,:,physics%YVELOCITY) = 0.
328  timedisc%pvar%data4d(:,:,:,physics%ZVELOCITY) = 0.
329  ! pressure
330  WHERE (mesh%radius%bcenter(:,:,:).LE.r0)
331  ! behind the shock front
332  timedisc%pvar%data4d(:,:,:,physics%PRESSURE) = p1
333  ELSEWHERE
334  ! in front of the shock front (ambient medium)
335  timedisc%pvar%data4d(:,:,:,physics%PRESSURE) = p0
336  END WHERE
337 
338  CALL physics%Convert2Conservative(timedisc%pvar,timedisc%cvar)
339  CALL mesh%Info(" DATA-----> initial condition: 3D Sedov explosion")
340 
341  END SUBROUTINE initdata
342 
343 END PROGRAM sedov3d
Mathematical functions.
Definition: functions.f90:48
subroutine initdata(Mesh, Physics, Fluxes, Timedisc)
Definition: bondi2d.f90:274
main fosite class
Definition: fosite.f90:71
program sedov3d
3D Sedov explosion
Definition: sedov3d.f90:35
elemental real function, public asinh(x)
inverse hyperbolic sine function
Definition: functions.f90:100
real rho0
Definition: solutions.f90:43
subroutine makeconfig(Sim, config)
Definition: bondi2d.f90:165
physics module for 1D,2D and 3D non-isothermal Euler equations
elemental real function, public acosh(x)
inverse hyperbolic cosine function
Definition: functions.f90:110
real gamma
Definition: solutions.f90:38