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