sgdisk.f90

Program and data initialization a self-gravitating disk (sgdisk)

Program and data initialization a self-gravitating disk (sgdisk)

Author
Jannes Klee
1!#############################################################################
2!# #
3!# fosite - 3D hydrodynamical simulation program #
4!# module: sgdisk.f90 #
5!# #
6!# Copyright (C) 2010-2024 #
7!# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8!# Jannes Klee <jklee@astrophysik.uni-kiel.de> #
9!# #
10!# This program is free software; you can redistribute it and/or modify #
11!# it under the terms of the GNU General Public License as published by #
12!# the Free Software Foundation; either version 2 of the License, or (at #
13!# your option) any later version. #
14!# #
15!# This program is distributed in the hope that it will be useful, but #
16!# WITHOUT ANY WARRANTY; without even the implied warranty of #
17!# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or #
18!# NON INFRINGEMENT. See the GNU General Public License for more #
19!# details. #
20!# #
21!# You should have received a copy of the GNU General Public License #
22!# along with this program; if not, write to the Free Software #
23!# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
24!# #
25!#############################################################################
26
27!----------------------------------------------------------------------------!
33!----------------------------------------------------------------------------!
34PROGRAM sgdisk
35 USE fosite_mod
36#ifdef NECSXAURORA
37 USE asl_unified
38#endif
39#ifdef HAVE_KROME
40 USE krome_main
41 USE krome_user
42#endif
43#ifdef PARALLEL
44#ifdef HAVE_MPI_MOD
45 USE mpi
46#endif
47#endif
48 IMPLICIT NONE
49#ifdef PARALLEL
50#ifdef HAVE_MPIF_H
51 include 'mpif.h'
52#endif
53#endif
54
55 !--------------------------------------------------------------------------!
56 ! general constants
57 REAL, PARAMETER :: GN = 6.6742d-8 ! grav. constant (cgs) !
58 REAL, PARAMETER :: RG = 8.31447d+7 ! molar gas constant (cgs) !
59 REAL, PARAMETER :: MSUN = 1.989d+33 ! solar mass [g] !
60 REAL, PARAMETER :: AU = 1.49597870691e+13 ! ast. unit [cm] !
61 REAL, PARAMETER :: YEAR = 3.15576e+7 ! Julian year [s] !
62 REAL, PARAMETER :: MSCALE = msun ! mass scaling param. !
63 ! simulation parameters
64 REAL, PARAMETER :: TSIM = 6.0 ! simulation time [ORP] !
65 REAL, PARAMETER :: MU = 2.35d+0 ! mean mol. mass [g/mol] !
66 REAL, PARAMETER :: VALPHA = 0.05 ! alpha visc. parameter !
67 ! disk & central object
68 REAL, PARAMETER :: MBH = 1.0*mscale ! central mass !
69 REAL, PARAMETER :: MDISK = 0.1*mscale ! initial disk mass !
70 REAL, PARAMETER :: T_INIT = 120.0 ! initial temperatur !
71 REAL, PARAMETER :: T_MIN = 10.0 ! minimal temperatur !
72 ! cooling parameters
73 REAL, PARAMETER :: BETA_C = 10.0 ! cooling parameter !
74 REAL, PARAMETER :: GAMMA = 1.6 ! adiabatic index !
75 ! mesh settings
76 INTEGER, PARAMETER :: MGEO = logcylindrical ! geometry of the mesh !
77 REAL, PARAMETER :: GPAR = au ! geom. scal. parameter !
78 REAL, PARAMETER :: RMIN = 1.0*gpar ! inner radius of the disk !
79 REAL, PARAMETER :: RMAX = 25.0*gpar ! outer radius of the grid !
80 INTEGER, PARAMETER :: XRES = 256 ! x-resolution !
81 INTEGER, PARAMETER :: YRES = xres*3 ! y-resolution !
82 INTEGER, PARAMETER :: ZRES = 1 ! z-resolution !
83 ! mestel
84 LOGICAL :: DAMP ! wave damping !
85 REAL, PARAMETER :: NOISE = 0.3 ! initial noise level !
86 ! output file parameter
87 INTEGER, PARAMETER :: ONUM = 100 ! number of outputs !
88 CHARACTER(LEN=256), PARAMETER &
89 :: ODIR = "./" ! output directory !
90 CHARACTER(LEN=256) :: OFNAME = 'sgdisk' ! output name !
91 !--------------------------------------------------------------------------!
92 CLASS(fosite), ALLOCATABLE :: Sim
93 REAL :: CSISO,OMEGA,ORP
94 !--------------------------------------------------------------------------!
95
96ALLOCATE(sim)
97
98#ifdef NECSXAURORA
99CALL asl_library_initialize()
100#endif
101
102CALL sim%InitFosite()
103CALL makeconfig(sim, sim%config)
104CALL sim%Setup()
105CALL initdata(sim%Mesh, sim%Physics, sim%Timedisc, sim%Fluxes, sim%Sources, &
106 sim%Timedisc%pvar, sim%Timedisc%cvar)
107CALL sim%Run()
108CALL sim%Finalize()
109
110#ifdef NECSXAURORA
111 CALL asl_library_finalize()
112#endif
113
114DEALLOCATE(sim)
115
116CONTAINS
117
118 SUBROUTINE makeconfig(Sim, config)
119 IMPLICIT NONE
120 !------------------------------------------------------------------------!
121 CLASS(fosite), INTENT(INOUT) :: Sim
122 TYPE(Dict_TYP), POINTER :: config
123 TYPE(Dict_TYP), POINTER :: mesh, physics, fluxes, boundary, grav,&
124 sources, timedisc, datafile, cooling, &
125 rotframe, pmass, self, damping
126 !------------------------------------------------------------------------!
127 ! some derived simulation parameters
128 csiso = sqrt(rg/mu*t_init)
129 omega = 0.0
130 orp = 2.*pi/(sqrt(gn*mbh/rmax**3.))
131 damp = .false.
132
133 ! mesh settings
134 ! stellar orbits must be inside the central hole of the mesh
135 mesh => dict(&
136 "meshtype" / midpoint, &
137 "geometry" / mgeo, &
138 "inum" / xres, &
139 "jnum" / yres, &
140 "knum" / zres, &
141 "xmin" / log(rmin/gpar), &
142 "xmax" / log(rmax/gpar), &
143 "ymin" / 0.0, &
144 "ymax" / (2.0*pi), &
145 "zmin" / 0.0, &
146 "zmax" / 0.0, &
147 "use_fargo" / 1, &
148 "fargo" / 2, &
149 "decomposition" / (/ -1, 1, 1/), &
150! "output/radius" / 1, &
151! "output/dl" / 1, &
152 "output/position_vector" / 1, &
153 "gparam" / gpar)
154
155
156 ! physics settings
157 physics => dict(&
158 "problem" / euler, &
159 "mu" / mu, &
160 "gamma" / gamma, &
161 "units" / cgs)
162! "output/bccsound" / 1)
163
164 ! boundary conditions
165 boundary => dict(&
166 "western" / custom,&
167 "eastern" / custom,&
168 "southern" / periodic, &
169 "northern" / periodic, &
170 "bottomer" / reflecting, &
171 "topper" / reflecting)
172
173
174 ! numerical fluxes and reconstruction method
175 fluxes => dict(&
176 "order" / linear, &
177 "fluxtype" / kt, &
178 "variables" / primitive, &
179 "limiter" / vanleer, &
180 "theta" / 1.2)
181
182
183 ! viscosity source term
184 rotframe => dict(&
185 "stype" / rotating_frame)
186
187
188 ! gravitational acceleration due to binary system
189 pmass => dict(&
190 "gtype" / pointmass, &
191 "mass" / mbh, &
192 "output/position" / 1)
193
194 ! cooling function
195 cooling => dict(&
196 "stype" / disk_cooling, &
197 "output/Qcool" / 1, &
198 "rhomin" / 1.0e-30, &
199 "method" / gammie, &
200 "b_cool" / beta_c)
201
202 ! self-gravity
203 self => dict(&
204 "gtype" / spectral, &
205 "output/potential" / 1, &
206 "self/green" / 1)
207
208 ! collect all gravity-source terms
209 grav => dict(&
210 "stype" / gravity, &
211 "pmass" / pmass, &
212 "self" / self, &
213 "output/potential" / 1, &
214 "energy" / 0, &
215 "output/height" / 1, &
216 "output/accel" / 1)
217
218 ! collect all source terms
219 sources => dict(&
220 "cooling" / cooling, &
221 "grav" / grav)
222
223 ! add wave damping if requested
224 IF (damp) &
225 CALL setattr(sources,"damping",damping)
226
227 ! time discretization settings
228 timedisc => dict(&
229 "method" / modified_euler, &
230 "cfl" / 0.3, &
231 "dtlimit" / 1.0e-50, &
232 "tol_rel" / 1.0e-3, &
233 "rhstype" / 1, &
234 "tol_abs" / (/ 1.0e-16, 1.0, 1.0e-16, 1.0 /), &
235 "output/energy" / 1, &
236 "output/rhs" / 1, &
237 "stoptime" / (orp*tsim), &
238 "pmin" / 1e-14, &
239 "tmin" / t_min, &
240 "checkdata" / ior(check_nothing,check_tmin), &
241 "maxiter" / 100000000)
242
243 ! initialize data input/output
244 datafile => dict(&
245 "fileformat" / xdmf, &
246 "filename" / (trim(odir) // trim(ofname)), &
247 "count" / onum)
248
249 config => dict(&
250 "physics" / physics, &
251 "fluxes" / fluxes, &
252 "mesh" / mesh, &
253 "boundary" / boundary, &
254 "sources" / sources, &
255 "timedisc" / timedisc, &
256 "datafile" / datafile)
257
258 END SUBROUTINE makeconfig
259
260
261 SUBROUTINE initdata(Mesh,Physics,Timedisc,Fluxes,Sources,pvar,cvar)
265 IMPLICIT NONE
266 !------------------------------------------------------------------------!
267 CLASS(mesh_base), INTENT(IN) :: Mesh
268 CLASS(physics_base), INTENT(INOUT) :: Physics
269 CLASS(timedisc_base), INTENT(INOUT) :: Timedisc
270 CLASS(fluxes_base), INTENT(INOUT) :: Fluxes
271 CLASS(sources_list),ALLOCATABLE,INTENT(INOUT) :: Sources
272 CLASS(marray_compound),INTENT(INOUT):: pvar,cvar
273 !------------------------------------------------------------------------!
274 ! Local variable declaration
275 CLASS(sources_base), POINTER :: sp => null()
276 INTEGER :: i,j,k
277#ifdef PARALLEL
278 INTEGER :: ierror
279#endif
280 REAL :: mass
281 REAL, DIMENSION(:,:,:), POINTER :: r, Sigma
282 REAL, DIMENSION(:,:,:,:), POINTER :: r_vec
283 CHARACTER(LEN=32) :: mdisk_str
284 REAL, DIMENSION(Mesh%IGMIN:Mesh%IGMAX,Mesh%JGMIN:Mesh%JGMAX,Mesh%KGMIN:Mesh%KGMAX) &
285 :: rands
286#ifdef NECSXAURORA
287 INTEGER :: rng, n
288#endif
289 !------------------------------------------------------------------------!
290 ! MESTEL'S DISK
291 ! distance from origin to cell bary centers and position vector
292 r => mesh%RemapBounds(mesh%radius%bcenter(:,:,:))
293 r_vec => mesh%RemapBounds(mesh%posvec%bcenter(:,:,:,:))
294 ! pointer to density array
295 sigma => mesh%RemapBounds(pvar%data4d(:,:,:,physics%DENSITY))
296
297 ! set surface density using radial power law (1/r) with a little noise
298#ifndef NECSXAURORA
299 CALL initrandseed(timedisc)
300 CALL random_number(rands)
301#else
302 CALL asl_random_create(rng, asl_randommethod_mt19937_64)
303 CALL asl_random_distribute_uniform(rng)
304 n = (mesh%IGMAX-mesh%IGMIN+1)*(mesh%JGMAX-mesh%JGMIN+1)*(mesh%KGMAX-mesh%KGMIN+1)
305 CALL asl_random_generate_d(rng, n, rands)
306#endif
307 rands = rands * noise * 2.0 + (1.0 - noise)
308 sigma = rands*(rmin/r(:,:,:))
309
310#ifdef NECSXAURORA
311 CALL asl_random_destroy(rng)
312#endif
313
314 ! determine disk mass
315 mass = sum(mesh%volume%data3d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX) * &
316 sigma(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX))
317#ifdef PARALLEL
318 CALL mpi_allreduce(mpi_in_place,mass,1,default_mpi_real,mpi_sum, &
319 mesh%comm_cart,ierror)
320#endif
321 ! rescale disk mass
322 sigma(:,:,:) = sigma(:,:,:) * mdisk / mass
323
324 ! 2. azimuthal velocity: balance initial radial acceleration with centrifugal acceleration
325 SELECT TYPE(phys => physics)
326 TYPE IS(physics_euler)
327 pvar%data4d(:,:,:,physics%PRESSURE) = &
328 csiso*csiso*pvar%data4d(:,:,:,physics%DENSITY)/gamma
329 ! necessary in order to calculte height below in UpdateGravity
330 SELECT TYPE(pvarious => pvar)
331 CLASS IS(statevector_euler)
332 CALL phys%UpdateSoundSpeed(pvarious)
333 END SELECT
334 END SELECT
335
336 ! reset velocities
337 pvar%data2d(:,physics%XVELOCITY:physics%YVELOCITY) = 0.0
338
339 ! check and update gravity
340 IF (ALLOCATED(sources)) &
341 sp => sources%GetSourcesPointer(gravity)
342 IF (ASSOCIATED(sp)) THEN
343 SELECT TYPE(sp)
344 CLASS IS(sources_gravity)
345 CALL sp%UpdateGravity(mesh,physics,fluxes,pvar,0.0,0.0)
346 ! ATTENTION: Don't use GetCentrifugalVelocity without the optional acceleration array!
347 ! This would yield undefined data, because GetCentrifugalVelocity calls ComputeRHS
348 ! which calls CenterBoundary. Since the FARFIELD boundary conditions are not
349 ! initialized at this stage (see below), the result is undefined.
350 pvar%data4d(:,:,:,physics%XVELOCITY:physics%XVELOCITY+physics%VDIM-1) = &
351 timedisc%GetCentrifugalVelocity(mesh,physics,fluxes,sources,(/0.,0.,1./),sp%accel%data4d)
352 CLASS DEFAULT
353 CALL physics%Error("sgdisk::InitData","this should not happen -> gravity pointer is not of class sources_gravity")
354 END SELECT
355 ELSE
356 CALL physics%Error("sgdisk::InitData","gravity source term not initialized")
357 END IF
358
359 IF (mesh%fargo%GetType().EQ.2) &
360 timedisc%w(:,:) = sqrt(physics%constants%GN*mbh/r(:,mesh%JMIN,:))-mesh%OMEGA*r(:,mesh%JMIN,:)
361
362 ! transform velocities to rotating frame
363 pvar%data4d(:,:,:,physics%YVELOCITY) = pvar%data4d(:,:,:,physics%YVELOCITY) &
364 - mesh%OMEGA*r(:,:,:)
365
366 ! get conservative variables
367 CALL physics%Convert2Conservative(pvar,cvar)
368
369 ! setting for custom boundary conditions (western boundary)
370 SELECT TYPE(bwest => timedisc%Boundary%boundary(west)%p)
371 CLASS IS (boundary_custom)
372 CALL bwest%SetCustomBoundaries(mesh,physics, &
373 (/custom_nograd,custom_outflow,custom_kepler,custom_nograd/))
374 END SELECT
375
376 ! setting for custom boundary conditions (eastern boundary)
377 SELECT TYPE(beast => timedisc%Boundary%boundary(east)%p)
378 CLASS IS (boundary_custom)
379 CALL beast%SetCustomBoundaries(mesh,physics, &
380 (/custom_nograd,custom_outflow,custom_kepler,custom_nograd/))
381 END SELECT
382
383 CALL physics%Convert2Conservative(pvar,cvar)
384 ! print some information
385 WRITE (mdisk_str, '(ES10.2)') mdisk
386 CALL mesh%Info(" DATA-----> initial condition: Mestel's disk")
387 CALL mesh%Info(" disk mass: " // trim(mdisk_str))
388
389 END SUBROUTINE initdata
390
391
392 SUBROUTINE initrandseed(Timedisc)
393 IMPLICIT NONE
394 !------------------------------------------------------------------------!
395 CLASS(timedisc_base),INTENT(IN) :: Timedisc
396 INTEGER :: i, n, clock
397 INTEGER, DIMENSION(:), ALLOCATABLE :: seed
398 !------------------------------------------------------------------------!
399 ! Initialize random number generator with a seed based on the systems time
400 ! source: http://gcc.gnu.org/onlinedocs/gfortran/RANDOM_005fSEED.html
401 CALL random_seed(size = n)
402 ALLOCATE(seed(n))
403 CALL system_clock(count=clock)
404 seed = clock + 37 * (/ (i - 1, i = 1, n) /)
405#ifdef PARALLEL
406 seed = seed + timedisc%GetRank()
407#endif
408 CALL random_seed(put = seed)
409 DEALLOCATE(seed)
410 END SUBROUTINE initrandseed
411
412
413END PROGRAM sgdisk
subroutine initdata(Mesh, Physics, Fluxes, Timedisc)
Definition: bondi2d.f90:274
subroutine makeconfig(Sim, config)
Definition: bondi2d.f90:165
subroutine initrandseed(Physics)
Definition: mestel.f90:371
physics module for 1D,2D and 3D non-isothermal Euler equations
generic source terms module providing functionaly common to all source terms
generic gravity terms module providing functionaly common to all gravity terms
program sgdisk
Definition: sgdisk.f90:34