48 REAL,
PARAMETER :: msun = 1.989e+30
49 REAL,
PARAMETER :: gn = 6.67408e-11
51 REAL,
PARAMETER :: tsim = 50.0
52 REAL,
PARAMETER :: accmass = 1.0*msun
53 REAL,
PARAMETER :: gamma = 1.4
55 REAL,
PARAMETER :: rhoinf = 3.351e-17
56 REAL,
PARAMETER :: csinf = 537.0
59 INTEGER,
PARAMETER :: mgeo = logspherical
60 INTEGER,
PARAMETER :: xres = 16
61 INTEGER,
PARAMETER :: yres = 6
62 INTEGER,
PARAMETER :: zres = 12
63 REAL,
PARAMETER :: rin = 0.1
64 REAL,
PARAMETER :: rout = 2.0
66 INTEGER,
PARAMETER :: onum = 10
67 CHARACTER(LEN=256),
PARAMETER &
69 CHARACTER(LEN=256),
PARAMETER &
75 CLASS(
fosite),
ALLOCATABLE :: sim
76 REAL,
DIMENSION(:),
ALLOCATABLE :: sigma
77 REAL :: sum_numer, sum_denom
78 INTEGER :: n,den,vel,pre
86 IF (sim%GetRank().EQ.0)
THEN
97 CALL initdata(sim%Mesh,sim%Physics,sim%Timedisc)
100 ok = .NOT.sim%aborted
102 IF (
ASSOCIATED(sim%Timedisc%solution))
THEN
103 ALLOCATE(sigma(sim%Physics%VNUM))
104 DO n=1,sim%Physics%VNUM
107 sum_numer = sum(abs(sim%Timedisc%pvar%data2d(:,n)-sim%Timedisc%solution%data2d(:,n)), &
108 mask=sim%Mesh%without_ghost_zones%mask1d(:))
109 sum_denom = sum(abs(sim%Timedisc%solution%data2d(:,n)),mask=sim%Mesh%without_ghost_zones%mask1d(:))
111 IF (sim%GetRank().GT.0)
THEN
112 CALL mpi_reduce(sum_numer,sum_numer,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
113 CALL mpi_reduce(sum_denom,sum_denom,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
115 CALL mpi_reduce(mpi_in_place,sum_numer,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
116 CALL mpi_reduce(mpi_in_place,sum_denom,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
118 sigma(n) = sum_numer / sum_denom
127 den = sim%Physics%DENSITY
128 vel = sim%Physics%XVELOCITY
129 pre = sim%Physics%PRESSURE
132 IF (sim%GetRank().EQ.0)
THEN
134tap_check(ok,
"stoptime reached")
136tap_check_small(sigma(den),2.0e-02,
"density deviation < 2%")
137tap_check_small(sigma(vel),2.0e-02,
"radial velocity deviation < 2%")
139tap_check_small(sigma(pre),1.0e-02,
"pressure deviation < 1%")
145 IF (
ALLOCATED(sigma))
DEALLOCATE(sigma)
155 TYPE(dict_typ),
POINTER :: config
159 TYPE(dict_typ),
POINTER :: mesh, physics, boundary, datafile, &
160 grav, pmass, timedisc, fluxes
161 REAL :: x1,x2,y1,y2,z1,z2
166 rb = gn * accmass / csinf**2
182 bc(bottom) = periodic
195 bc(bottom) = periodic
198 CALL sim%Physics%Error(
"bondi3d::MakeConfig",
"geometry currently not supported")
202 "meshtype" / midpoint, &
213 "output/radius" / 1, &
218 "western" / bc(west), &
219 "eastern" / bc(east), &
220 "southern" / bc(south), &
221 "northern" / bc(north), &
222 "bottomer" / bc(bottom), &
234 "variables" / primitive, &
235 "limiter" / monocent, &
240 "gtype" / pointmass, &
251 "method" / modified_euler, &
254 "stoptime" / (tsim * tau), &
255 "dtlimit" / (1.0e-6 * tau), &
256 "output/solution" / 1, &
261 "fileformat" / xdmf, &
262 "filename" / (trim(odir) // trim(ofname)), &
267 "physics" / physics, &
268 "boundary" / boundary, &
270 "sources/grav" / grav, &
271 "timedisc" / timedisc, &
272 "datafile" / datafile)
279 CLASS(physics_base),
INTENT(IN) :: Physics
280 CLASS(mesh_base),
INTENT(IN) :: Mesh
281 CLASS(timedisc_base),
INTENT(INOUT) :: Timedisc
286 CHARACTER(LEN=64) :: info_str
289 SELECT TYPE(pvar => timedisc%pvar)
290 TYPE IS(statevector_euler)
292 pvar%density%data1d(:) = rhoinf
293 pvar%velocity%data1d(:) = 0.
294 pvar%pressure%data1d(:) = rhoinf * csinf**2 / gamma
296 CALL physics%Error(
"bondi3d::InitData",
"only non-isothermal HD supported")
299 CALL physics%Convert2Conservative(timedisc%pvar,timedisc%cvar)
303 IF (
ASSOCIATED(timedisc%solution))
THEN
305 SELECT TYPE(pvar => timedisc%solution)
306 TYPE IS(statevector_euler)
307 DO k=mesh%KMIN,mesh%KMAX
308 DO j=mesh%JMIN,mesh%JMAX
309 DO i=mesh%IMIN,mesh%IMAX
310 r = mesh%radius%bcenter(i,j,k)
311 CALL bondi(r/rb,gamma,rhoinf,csinf,rho,vr)
312 cs2 = csinf**2 * (rho/rhoinf)**(gamma-1.0)
313 pvar%density%data3d(i,j,k) = rho
318 pvar%velocity%data4d(i,j,k,l) = sign(&
319 max(epsilon(cs2),abs(vr*mesh%posvec%bcenter(i,j,k,l)/r)), &
320 vr*mesh%posvec%bcenter(i,j,k,l))
322 pvar%pressure%data3d(i,j,k) = rho * cs2 / gamma
331 SELECT TYPE(beast => timedisc%Boundary%boundary(east)%p)
332 CLASS IS (boundary_custom)
334 CALL beast%SetCustomBoundaries(mesh,physics, &
335 (/custom_fixed,custom_nograd,custom_fixed,custom_fixed,custom_fixed/))
336 DO k=mesh%KMIN,mesh%KMAX
337 DO j=mesh%JMIN,mesh%JMAX
340 r = mesh%radius%bcenter(mesh%IMAX+i,j,k)
341 CALL bondi(r/rb,gamma,rhoinf,csinf,rho,vr)
342 cs2 = csinf**2 * (rho/rhoinf)**(gamma-1.0)
343 beast%data(i,j,k,physics%DENSITY) = rho
345 beast%data(i,j,k,physics%XVELOCITY+l-1) &
346 = vr*mesh%posvec%bcenter(mesh%IMAX+i,j,k,l)/r
348 beast%data(i,j,k,physics%PRESSURE) = rho * cs2 / gamma
354 WRITE(info_str,
"(ES10.3)") rb
355 CALL mesh%Info(
" " //
"Bondi radius: " &
356 // trim(info_str) //
" m")
357 WRITE(info_str,
"(ES10.3)") tau
358 CALL mesh%Info(
" " //
"Free fall time: " &
359 // trim(info_str) //
" s")
363 SUBROUTINE bondi(r,gamma,rhoinf,csinf,rho,vr)
378 REAL,
INTENT(IN) :: r,gamma,rhoinf,csinf
379 REAL,
INTENT(OUT) :: rho,vr
382 PURE SUBROUTINE funcd(x,fx,dfx,plist)
384 REAL,
INTENT(IN) :: x
385 REAL,
INTENT(IN),
DIMENSION(:),
OPTIONAL :: plist
386 REAL,
INTENT(OUT) :: fx,dfx
390 REAL,
PARAMETER :: xacc = 1.0e-6
391 REAL :: gp1,gm1,g35,rc,chi,lambda,psi,gr
393 COMMON /funcd_parameter/ gm1, gr
398 g35 = 0.5 * (5.0-3.0*gamma)
403 lambda = 0.25 * g35**(-g35/gm1)
407 gr = chi**(2.*gm1/gp1) * (1./gm1 + 1./r)
415 rho = rhoinf * chi**(-2./gp1) / psi
416 vr = -csinf * chi**(-gm1/gp1) * psi
424PURE SUBROUTINE funcd(y,fy,dfy,plist)
427 REAL,
INTENT(IN) :: y
428 REAL,
INTENT(OUT) :: fy,dfy
429 REAL,
INTENT(IN),
DIMENSION(:),
OPTIONAL :: plist
432 COMMON /funcd_parameter/ gm1,gr
434 fy = 0.5*y*y + y**(-gm1) / gm1 - gr
435 dfy = y - y**(-gm1-1.)
subroutine initdata(Mesh, Physics, Fluxes, Timedisc)
pure subroutine funcd(y, fy, dfy, plist)
subroutine makeconfig(Sim, config)
subroutine bondi(r, gamma, rhoinf, csinf, rho, vr)
program bondi3d
Program and data initialization for 3D Bondi accretion.
subroutine, public getroot_newton(funcd, x1, x2, root, error, plist, xm, iterations)