48 REAL,
PARAMETER :: msun = 1.989e+30
49 REAL,
PARAMETER :: gn = 6.67408e-11
51 REAL,
PARAMETER :: tsim = 20.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
58 INTEGER,
PARAMETER :: mgeo = spherical
59 INTEGER,
PARAMETER :: xres = 100
60 INTEGER,
PARAMETER :: yres = 4
61 INTEGER,
PARAMETER :: zres = 4
62 REAL,
PARAMETER :: rin = 0.1
63 REAL,
PARAMETER :: rout = 2.0
65 INTEGER,
PARAMETER :: onum = 10
66 CHARACTER(LEN=256),
PARAMETER &
68 CHARACTER(LEN=256),
PARAMETER &
74 CLASS(
fosite),
ALLOCATABLE :: sim
75 REAL,
DIMENSION(:),
ALLOCATABLE :: sigma
76 REAL :: sum_numer, sum_denom
77 INTEGER :: n,den,vel,pre
85 IF (sim%GetRank().EQ.0)
THEN 96 CALL initdata(sim%Mesh,sim%Physics,sim%Timedisc)
101 IF (
ASSOCIATED(sim%Timedisc%solution))
THEN 102 ALLOCATE(sigma(sim%Physics%VNUM))
103 DO n=1,sim%Physics%VNUM
106 sum_numer = sum(abs(sim%Timedisc%pvar%data4d(sim%Mesh%IMIN:sim%Mesh%IMAX,&
107 sim%Mesh%JMIN:sim%Mesh%JMAX,sim%Mesh%KMIN:sim%Mesh%KMAX,n) &
108 -sim%Timedisc%solution%data4d(sim%Mesh%IMIN:sim%Mesh%IMAX,&
109 sim%Mesh%JMIN:sim%Mesh%JMAX,sim%Mesh%KMIN:sim%Mesh%KMAX,n)))
110 sum_denom = sum(abs(sim%Timedisc%solution%data4d(sim%Mesh%IMIN:sim%Mesh%IMAX,&
111 sim%Mesh%JMIN:sim%Mesh%JMAX,sim%Mesh%KMIN:sim%Mesh%KMAX,n)))
113 IF (sim%GetRank().GT.0)
THEN 114 CALL mpi_reduce(sum_numer,sum_numer,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
115 CALL mpi_reduce(sum_denom,sum_denom,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
117 CALL mpi_reduce(mpi_in_place,sum_numer,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
118 CALL mpi_reduce(mpi_in_place,sum_denom,1,default_mpi_real,mpi_sum,0,mpi_comm_world,sim%ierror)
120 sigma(n) = sum_numer / sum_denom
129 den = sim%Physics%DENSITY
130 vel = sim%Physics%XVELOCITY
131 pre = sim%Physics%PRESSURE
134 IF (sim%GetRank().EQ.0)
THEN 136 tap_check(ok,
"stoptime reached")
138 tap_check_small(sigma(den),4.0e-02,
"density deviation < 4%")
139 tap_check_small(sigma(vel),4.0e-02,
"radial velocity deviation < 4%")
141 tap_check_small(sigma(pre),6.0e-02,
"pressure deviation < 6%")
147 IF (
ALLOCATED(sigma))
DEALLOCATE(sigma)
157 TYPE(Dict_TYP),
POINTER :: config
161 TYPE(Dict_TYP),
POINTER :: mesh, physics, boundary, datafile, &
162 grav, pmass, timedisc, fluxes
163 REAL :: x1,x2,y1,y2,z1,z2
168 rb = gn * accmass / csinf**2
184 bc(bottom) = periodic
187 CALL sim%Physics%Error(
"bondi3d::MakeConfig",
"geometry currently not supported")
191 "meshtype" / midpoint, &
202 "output/radius" / 1, &
207 "western" / bc(west), &
208 "eastern" / bc(east), &
209 "southern" / bc(south), &
210 "northern" / bc(north), &
211 "bottomer" / bc(bottom), &
223 "variables" / primitive, &
224 "limiter" / monocent, &
229 "gtype" / pointmass, &
240 "method" / modified_euler, &
243 "stoptime" / (tsim * tau), &
244 "dtlimit" / (1.0e-6 * tau), &
245 "output/solution" / 1, &
250 "fileformat" / vtk, &
251 "filename" / (trim(odir) // trim(ofname)), &
256 "physics" / physics, &
257 "boundary" / boundary, &
259 "sources/grav" / grav, &
260 "timedisc" / timedisc, &
261 "datafile" / datafile)
265 SUBROUTINE initdata(Mesh,Physics,Timedisc)
268 CLASS(physics_base),
INTENT(IN) :: Physics
269 CLASS(mesh_base),
INTENT(IN) :: Mesh
270 CLASS(timedisc_base),
INTENT(INOUT) :: Timedisc
275 CHARACTER(LEN=64) :: info_str
278 SELECT TYPE(pvar => timedisc%pvar)
279 TYPE IS(statevector_euler)
281 pvar%density%data1d(:) = rhoinf
282 pvar%velocity%data1d(:) = 0.
283 pvar%pressure%data1d(:) = rhoinf * csinf**2 / gamma
285 CALL physics%Error(
"bondi3d::InitData",
"only non-isothermal HD supported")
288 CALL physics%Convert2Conservative(timedisc%pvar,timedisc%cvar)
292 IF (
ASSOCIATED(timedisc%solution))
THEN 294 SELECT TYPE(pvar => timedisc%solution)
295 TYPE IS(statevector_euler)
296 DO k=mesh%KMIN,mesh%KMAX
297 DO j=mesh%JMIN,mesh%JMAX
298 DO i=mesh%IMIN,mesh%IMAX
299 r = mesh%radius%bcenter(i,j,k)
300 CALL bondi(r/rb,gamma,rhoinf,csinf,rho,vr)
301 cs2 = csinf**2 * (rho/rhoinf)**(gamma-1.0)
302 pvar%density%data3d(i,j,k) = rho
307 pvar%velocity%data4d(i,j,k,l) = sign(&
308 max(epsilon(cs2),abs(vr*mesh%posvec%bcenter(i,j,k,l)/r)), &
309 vr*mesh%posvec%bcenter(i,j,k,l))
311 pvar%pressure%data3d(i,j,k) = rho * cs2 / gamma
320 SELECT TYPE(beast => timedisc%Boundary%boundary(east)%p)
321 CLASS IS (boundary_custom)
323 CALL beast%SetCustomBoundaries(mesh,physics, &
324 (/custom_fixed,custom_nograd,custom_fixed,custom_fixed,custom_fixed/))
325 DO k=mesh%KMIN,mesh%KMAX
326 DO j=mesh%JMIN,mesh%JMAX
329 r = mesh%radius%bcenter(mesh%IMAX+i,j,k)
330 CALL bondi(r/rb,gamma,rhoinf,csinf,rho,vr)
331 cs2 = csinf**2 * (rho/rhoinf)**(gamma-1.0)
332 beast%data(i,j,k,physics%DENSITY) = rho
334 beast%data(i,j,k,physics%XVELOCITY+l-1) &
335 = vr*mesh%posvec%bcenter(mesh%IMAX+i,j,k,l)/r
337 beast%data(i,j,k,physics%PRESSURE) = rho * cs2 / gamma
343 WRITE(info_str,
"(ES9.3)") rb
344 CALL mesh%Info(
" " //
"Bondi radius: " &
345 // trim(info_str) //
" m")
346 WRITE(info_str,
"(ES9.3)") tau
347 CALL mesh%Info(
" " //
"Free fall time: " &
348 // trim(info_str) //
" s")
352 SUBROUTINE bondi(r,gamma,rhoinf,csinf,rho,vr)
367 REAL,
INTENT(IN) :: r,gamma,rhoinf,csinf
368 REAL,
INTENT(OUT) :: rho,vr
371 PURE SUBROUTINE funcd(x,fx,dfx,plist)
373 REAL,
INTENT(IN) :: x
374 REAL,
INTENT(IN),
DIMENSION(:),
OPTIONAL :: plist
375 REAL,
INTENT(OUT) :: fx,dfx
379 REAL,
PARAMETER :: xacc = 1.0e-6
380 REAL :: gp1,gm1,g35,rc,chi,lambda,psi,gr
382 COMMON /funcd_parameter/ gm1, gr
387 g35 = 0.5 * (5.0-3.0*gamma)
392 lambda = 0.25 * g35**(-g35/gm1)
396 gr = chi**(2.*gm1/gp1) * (1./gm1 + 1./r)
404 rho = rhoinf * chi**(-2./gp1) / psi
405 vr = -csinf * chi**(-gm1/gp1) * psi
413 PURE SUBROUTINE funcd(y,fy,dfy,plist)
416 REAL,
INTENT(IN) :: y
417 REAL,
INTENT(OUT) :: fy,dfy
418 REAL,
INTENT(IN),
DIMENSION(:),
OPTIONAL :: plist
421 COMMON /funcd_parameter/ gm1,gr
423 fy = 0.5*y*y + y**(-gm1) / gm1 - gr
424 dfy = y - y**(-gm1-1.)
pure subroutine funcd(y, fy, dfy, plist)
subroutine, public getroot_newton(funcd, x1, x2, root, error, plist, xm, iterations)
subroutine initdata(Mesh, Physics, Fluxes, Timedisc)
subroutine makeconfig(Sim, config)
program bondi3d
Program and data initialization for 3D Bondi accretion.
subroutine bondi(r, gamma, rhoinf, csinf, rho, vr)