81 REAL,
POINTER :: accrate
82 REAL,
POINTER :: massloss
86 REAL,
DIMENSION(:,:),
POINTER :: pos
87 REAL,
DIMENSION(:),
POINTER :: r0
88 REAL,
DIMENSION(:,:,:),
POINTER :: r_prim
89 REAL,
DIMENSION(:,:,:,:),
POINTER :: fr_prim
90 REAL,
DIMENSION(:,:,:,:),
POINTER :: posvec_prim
91 REAL,
DIMENSION(:,:,:,:),
POINTER :: posvec_prim_tmp
92 REAL,
DIMENSION(:,:,:,:,:),
POINTER :: fposvec_prim
141 TYPE(
dict_typ),
POINTER :: config,IO
143 INTEGER :: potential_number, valwrite, gtype
144 INTEGER :: err,i,j,k,l
145 REAL :: r_schwarzschild=0.0,eps
147 CALL this%InitGravity(mesh,physics,
"central point mass",config,io)
149 ALLOCATE(this%potential, this%pot, this%omega, this%omega2, &
150 this%r_prim(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX),&
151 this%fr_prim(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,3), &
152 this%posvec_prim(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,3),&
153 this%posvec_prim_tmp(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,3),&
154 this%fposvec_prim(mesh%IGMIN:mesh%IGMAX,mesh%JGMIN:mesh%JGMAX,mesh%KGMIN:mesh%KGMAX,3,3),&
156 this%mass, this%accrate, this%massloss, this%pos(1,3), &
158 IF (err.NE.0)
CALL this%Error(
"InitGravity_pointmass",
"Memory allocation failed!")
161 CALL getattr(config,
"potential", potential_number,
newton)
162 CALL this%potential%InitLogging(potential_number,
potential_name(potential_number))
168 this%pot%data1d(:) = 0.0
169 this%omega%data1d(:) = 0.0
170 this%omega2%data1d(:) = 0.0
173 CALL getattr(config,
"mass", this%mass, 1.0)
174 CALL setattr(io,
"mass", ref(this%mass))
177 CALL getattr(config,
"x", this%pos(1,1), 0.0)
178 CALL getattr(config,
"y", this%pos(1,2), 0.0)
179 CALL getattr(config,
"z", this%pos(1,3), 0.0)
182 CALL getattr(config,
"softening", eps, 0.0)
185 CALL getattr(config,
"switchon", this%switchon, -1.0)
190 CALL getattr(config,
"acclimit", this%acclimit, -1.0)
192 CALL setattr(io,
"accrate", ref(this%accrate))
193 IF (this%acclimit.GT.0.0) &
194 CALL setattr(io,
"massloss", ref(this%massloss))
196 SELECT CASE(potential_number)
198 r_schwarzschild = 0.0
201 r_schwarzschild = 2.*physics%constants%GN * this%mass / physics%constants%C**2
203 CALL this%Error(
"InitGravity_pointmass",
"potential must be either NEWTON or WIITA")
213 IF (all(abs(this%pos(1,:)).LE.tiny(this%pos)))
THEN
216 this%posvec_prim(:,:,:,:) = mesh%posvec%bcenter(:,:,:,:)
217 this%r_prim(:,:,:) = mesh%radius%bcenter(:,:,:)
218 this%fr_prim(:,:,:,1) = mesh%radius%faces(:,:,:,
east)
219 this%fr_prim(:,:,:,2) = mesh%radius%faces(:,:,:,
north)
220 this%fr_prim(:,:,:,3) = mesh%radius%faces(:,:,:,
top)
227 this%posvec_prim_tmp(:,:,:,1) = this%pos(1,1)
228 this%posvec_prim_tmp(:,:,:,2) = this%pos(1,2)
229 this%posvec_prim_tmp(:,:,:,3) = this%pos(1,3)
231 CALL mesh%Geometry%Convert2Curvilinear(mesh%curv%faces(:,:,:,
east,:), &
232 this%posvec_prim_tmp(:,:,:,:),this%fposvec_prim(:,:,:,1,:))
233 CALL mesh%Geometry%Convert2Curvilinear(mesh%curv%faces(:,:,:,
north,:), &
234 this%posvec_prim_tmp(:,:,:,:),this%fposvec_prim(:,:,:,2,:))
235 CALL mesh%Geometry%Convert2Curvilinear(mesh%curv%faces(:,:,:,
top,:), &
236 this%posvec_prim_tmp(:,:,:,:),this%fposvec_prim(:,:,:,3,:))
238 CALL mesh%Geometry%Convert2Curvilinear(mesh%bcenter,this%posvec_prim_tmp,this%posvec_prim)
243 this%posvec_prim(:,:,:,:) = mesh%posvec%bcenter(:,:,:,:) - this%posvec_prim(:,:,:,:)
244 this%fposvec_prim(:,:,:,1,:) = mesh%posvec%faces(:,:,:,
east,:) - this%fposvec_prim(:,:,:,1,:)
245 this%fposvec_prim(:,:,:,2,:) = mesh%posvec%faces(:,:,:,
north,:) - this%fposvec_prim(:,:,:,2,:)
246 this%fposvec_prim(:,:,:,3,:) = mesh%posvec%faces(:,:,:,
top,:) - this%fposvec_prim(:,:,:,3,:)
248 this%r_prim(:,:,:) = sqrt(this%posvec_prim(:,:,:,1)**2 &
249 + this%posvec_prim(:,:,:,2)**2 + this%posvec_prim(:,:,:,3)**2)
250 this%fr_prim(:,:,:,1) = sqrt(this%fposvec_prim(:,:,:,1,1)**2 &
251 + this%fposvec_prim(:,:,:,1,2)**2 + this%fposvec_prim(:,:,:,1,3)**2)
252 this%fr_prim(:,:,:,2) = sqrt(this%fposvec_prim(:,:,:,2,1)**2 &
253 + this%fposvec_prim(:,:,:,2,2)**2 + this%fposvec_prim(:,:,:,2,3)**2)
254 this%fr_prim(:,:,:,3) = sqrt(this%fposvec_prim(:,:,:,3,1)**2 &
255 +this%fposvec_prim(:,:,:,3,2)**2 + this%fposvec_prim(:,:,:,3,3)**2)
263 DO k=mesh%KGMIN,mesh%KGMAX
264 DO j=mesh%JGMIN,mesh%JGMAX
266 DO i=mesh%IGMIN,mesh%IGMAX
271 this%omega2%data3d(i,j,k) = 1./ max(10*tiny(eps), &
272 (( this%r_prim(i,j,k) * (this%r_prim(i,j,k)-r_schwarzschild)**2) + eps**3) / (physics%Constants%GN*this%mass) )
273 this%omega%data3d(i,j,k) = sqrt(this%omega2%data3d(i,j,k))
278 this%accel%data4d(i,j,k,l) = -this%omega2%data3d(i,j,k) * this%posvec_prim(i,j,k,physics%VIDX(l))
285 CALL this%CalcPotential(mesh,physics,this%mass,this%r_prim,this%fr_prim,this%pot%data4d)
287 CALL this%SetOutput(mesh,physics,config,io)
291 SELECT TYPE(geo=>mesh%geometry)
293 CALL getattr(config,
"outbound", this%outbound,
west)
295 CALL getattr(config,
"outbound", this%outbound,
west)
297 CALL getattr(config,
"outbound", this%outbound, 0)
298 CALL this%WARNING(
"GravitySources_pointmass",
"geometry does not support accretion")
300 CALL this%InfoGravity()
310 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX), &
312 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX,3), &
313 INTENT(IN) :: dist_faces
314 REAL,
DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX,4), &
319 pot(:,:,:,1) = - physics%constants%GN * mass / dist(:,:,:)
320 pot(:,:,:,2) = - physics%constants%GN * mass / dist_faces(:,:,:,1)
321 pot(:,:,:,3) = - physics%constants%GN * mass / dist_faces(:,:,:,2)
322 pot(:,:,:,4) = - physics%constants%GN * mass / dist_faces(:,:,:,3)
330 CHARACTER(LEN=32) :: param_str
332 WRITE (param_str,
'(ES10.2)') this%mass
333 CALL this%Info(
" potential: " // &
334 trim(this%potential%GetName()))
335 CALL this%Info(
" initial mass: " // trim(param_str))
336 WRITE (param_str,
'(3(ES10.2))') this%pos(1,1:3)
337 CALL this%Info(
" cart. position: " // trim(param_str))
338 IF (this%outbound.GT.0)
THEN
339 param_str =
"enabled"
341 param_str =
"disabled"
343 CALL this%Info(
" accretion: " // trim(param_str))
344 IF (this%outbound.GT.0.AND.this%acclimit.GT.0.0)
THEN
345 WRITE (param_str,
'(ES10.2)') this%acclimit
346 CALL this%Info(
" accretion limit: " // trim(param_str))
348 IF (this%switchon.GT.0.0)
THEN
349 WRITE (param_str,
'(ES10.2)') this%switchon
350 CALL this%Info(
" switchon time: " // trim(param_str))
360 TYPE(
dict_typ),
POINTER :: config,IO
366 CALL getattr(config,
"output/position", valwrite, 0)
367 IF (valwrite .EQ. 1) &
368 CALL setattr(io,
"position", this%pos)
370 CALL getattr(config,
"output/potential", valwrite, 0)
371 IF ((valwrite .EQ. 1).AND.
ALLOCATED(this%pot))
THEN
372 IF (
ASSOCIATED(this%pot%data4d)) &
373 CALL setattr(io,
"potential", &
374 this%pot%data4d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX,4))
391 REAL,
INTENT(IN) :: time,dt
394 REAL,
DIMENSION(Physics%VNUM) :: bflux
395 REAL :: scaling,oldmass,massfac,sqrmassfac,dmass,dmasslim
398 IF (this%outbound.NE.0)
THEN
401 bflux(:) = fluxes%GetBoundaryFlux(mesh,physics,this%outbound,mpi_comm_world)
403 bflux(:) = fluxes%GetBoundaryFlux(mesh,physics,this%outbound)
411 dmass = (bflux(physics%DENSITY) - this%mdot)
412 IF(this%acclimit.GE.0.)
THEN
413 dmasslim = min(dmass,this%acclimit*dt*this%mass)
414 this%massloss = this%massloss + dmass - dmasslim
418 this%mass = this%mass + dmass
419 IF (dt.GT.0.0) this%accrate = dmass/dt
422 massfac = this%mass/oldmass
423 sqrmassfac = sqrt(massfac)
424 this%accel%data1d(:) = this%accel%data1d(:) * massfac
425 this%pot%data1d(:) = this%pot%data1d(:) * massfac
426 this%omega%data1d(:) = this%omega%data1d(:) * sqrmassfac
427 this%mdot = bflux(physics%DENSITY)
431 IF (time.GE.0.0.AND.time.LE.this%switchon)
THEN
433 scaling = sin(0.5*pi*time/this%switchon)**2
437 DO k=mesh%KGMIN,mesh%KGMAX
438 DO j=mesh%JGMIN,mesh%JGMAX
440 DO i=mesh%IGMIN,mesh%IGMAX
443 this%accel%data4d(i,j,k,l) = -scaling * this%omega2%data3d(i,j,k) * this%posvec_prim(i,j,k,physics%VIDX(l))
463 TYPE(
marray_base),
INTENT(INOUT) :: bccsound,h_ext,height
474 CHARACTER(LEN=128) :: buffer
476 IF (this%GetRank().EQ.0)
THEN
477 CALL this%Info(
"-------------------------------------------------------------------")
478 WRITE(buffer,
"(A,(ES11.3))")
" central mass: ", this%mass
479 CALL this%Info(buffer)
480 IF (this%acclimit.GT.0.0)
THEN
481 WRITE(buffer,
"(A,(ES11.3))")
" mass loss: ", this%massloss
482 CALL this%Info(buffer)
486 DEALLOCATE(this%omega,this%omega2,this%r_prim,this%fr_prim, &
487 this%posvec_prim,this%posvec_prim_tmp,this%fposvec_prim,this%mass, &
488 this%accrate,this%massloss,this%pos)
490 IF (
ALLOCATED(this%potential))
DEALLOCATE(this%potential)
491 IF (
ALLOCATED(this%pot))
DEALLOCATE(this%pot)
492 CALL this%Finalize_base()
507 REAL,
INTENT(IN) :: cs,
omega
Dictionary for generic data types.
type(logging_base), save this
base module for numerical flux functions
defines properties of a 3D cylindrical mesh
defines properties of a 3D logcylindrical mesh
defines properties of a 3D spherical mesh
generic gravity terms module providing functionaly common to all gravity terms
source terms module for gravitational acceleration due to a point mass at the center of the coordinat...
integer, parameter, public wiita
character(len=16), dimension(2), parameter potential_name
subroutine updategravity_single(this, Mesh, Physics, Fluxes, pvar, time, dt)
updates the gravitational acceleration of the pointmass module
subroutine infogravity(this)
subroutine calcpotential(this, Mesh, Physics, mass, dist, dist_faces, pot)
subroutine initgravity_pointmass(this, Mesh, Physics, config, IO)
constructor for point mass module
integer, parameter, public newton
pure subroutine calcdiskheight_single(this, Mesh, Physics, pvar, bccsound, h_ext, height)
computes pressure scale height of a geometrically thin Keplerian disk
elemental real function, public getdiskheight(cs, omega)
return pressure scale height of a geometrically thin Keplerian disk
subroutine finalize(this)
Destructor of logging_base class.
base class for mesh arrays
derived class for compound of mesh arrays
integer, parameter east
named constant for eastern boundary
subroutine setoutput(this, config, IO)
Setup mesh fields for i/o.
integer, parameter top
named constant for top boundary
integer, parameter north
named constant for northern boundary
integer, parameter west
named constant for western boundary
pure real function, dimension(size(ephir%data2d, dim=1)) omega(ephir, velocity)