collapse.f90
Go to the documentation of this file.
1!#############################################################################
2!# #
3!# fosite - 3D hydrodynamical simulation program #
4!# module: collapse.f90 #
5!# #
6!# Copyright (C) 2008-2024 #
7!# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8!# Björn Sperling <sperling@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!----------------------------------------------------------------------------!
42!----------------------------------------------------------------------------!
43PROGRAM collapse
44 USE fosite_mod
45#include "tap.h"
46 IMPLICIT NONE
47 !--------------------------------------------------------------------------!
48 REAL, PARAMETER :: gn = 6.6742e-11 ! [m^3/kg/s^2]
49 ! simulation parameters
50 REAL, PARAMETER :: tsim = 1.0e-0 ! simulation time in terms of the
51 ! free-fall time [TAU]
52 REAL, PARAMETER :: gamma = 1.4 ! ratio of specific heats
53 REAL, PARAMETER :: mass = 1.0e+0 ! mass of spheroid
54 REAL, PARAMETER :: centmass = 1.0e+2 ! central pointmass
55 REAL, PARAMETER :: rsph = 30.0 ! semi-minor axis of the spheroid
56 REAL, PARAMETER :: ecc = 0.0 ! eccentricity (0.0 is sphere)
57 REAL, PARAMETER :: vol0 = 4*pi/3 * rsph*rsph*rsph / (1.-ecc*ecc)
58 ! volume of the spheroid
59 REAL, PARAMETER :: omega = 1.0e-7 ! angular velocity (0.0 to disable)
60 REAL, PARAMETER :: omega_frame = 0.0*omega ! angular velocity (0.0 to disable)
61 REAL, PARAMETER :: eta_p = 100.0 ! ratio of p_(hydro_static) to p
62 ! (in case of self-gravity) approx
63 ! 100 (free fall); approx 1 stable
64 ! (without pointmass)
65 REAL, PARAMETER :: eta_rho = 1.0e-6 ! density ratio rho / rho_inf
66 ! mesh settings
67! INTEGER, PARAMETER :: MGEO = SPHERICAL ! geometry of the mesh
68 INTEGER, PARAMETER :: mgeo = cylindrical
69! INTEGER, PARAMETER :: MGEO = TANCYLINDRICAL
70 INTEGER, PARAMETER :: xres = 150 ! x-resolution
71 INTEGER, PARAMETER :: yres = 1 !XRES ! y-resolution
72 INTEGER, PARAMETER :: zres = xres ! z-resolution
73 REAL, PARAMETER :: rmax = 1.5 ! size of comput. domain in [RSPH]
74 REAL, PARAMETER :: gpar = 0.5*rsph ! geometry scaling parameter
75 ! output parameters
76 INTEGER, PARAMETER :: onum = 10 ! number of output data sets
77 CHARACTER(LEN=256), PARAMETER & ! output data dir
78 :: odir = './'
79 CHARACTER(LEN=256), PARAMETER & ! output data file name
80 :: ofname = 'collapse_cyl_rhs1_150'
81 !--------------------------------------------------------------------------!
82 REAL :: tau ! free-fall time scale
83 REAL :: rho0 ! initial density of the sphere
84 REAL :: p0 ! initial hydrostatic pressure
85 !--------------------------------------------------------------------------!
86 CLASS(fosite),ALLOCATABLE :: sim
87 LOGICAL :: ok
88 !--------------------------------------------------------------------------!
89 ALLOCATE(sim)
90 CALL sim%InitFosite()
91
92#ifdef PARALLEL
93 IF (sim%GetRank().EQ.0) THEN
94#endif
95tap_plan(1)
96#ifdef PARALLEL
97 END IF
98#endif
99
100 CALL makeconfig(sim, sim%config)
101
102! CALL PrintDict(config)
103
104 CALL sim%Setup()
105
106 ! set initial condition
107 CALL initdata(sim%Mesh, sim%Physics, sim%Timedisc)
108
109 CALL sim%Run()
110 ok = .NOT.sim%aborted
111
112#ifdef PARALLEL
113 IF (sim%GetRank().EQ.0) THEN
114#endif
115 tap_check(ok,"Finished simulation")
116 tap_done
117#ifdef PARALLEL
118 END IF
119#endif
120
121 CALL sim%Finalize()
122 DEALLOCATE(sim)
123
124
125 CONTAINS
126
127 SUBROUTINE makeconfig(Sim, config)
128 IMPLICIT NONE
129 !------------------------------------------------------------------------!
130 CLASS(fosite) :: Sim
131 TYPE(dict_typ),POINTER :: config
132 !------------------------------------------------------------------------!
133 ! Local variable declaration
134 INTEGER :: bc(6),sgbc
135 TYPE(dict_typ), POINTER :: mesh,physics, boundary, datafile, rotframe, &
136 sources, timedisc, fluxes, grav, pmass, selfgravity
137 REAL :: x1,x2,y1,y2,z1,z2
138 !------------------------------------------------------------------------!
139 INTENT(INOUT) :: sim
140 !------------------------------------------------------------------------!
141 ! mesh settings and boundary conditions
142 SELECT CASE(mgeo)
143 CASE(spherical)
144 x2 = rmax*rsph
145 x1 = 2.*x2 / (xres+2) ! x_min = 2*dx
146 y1 = 0.005
147 y2 = pi-0.005
148 z1 = 0.0
149 z2 = 2.*pi
150 CASE(cylindrical)
151 x2 = rmax*rsph
152 x1 = 2.*x2 / (xres+2) ! x_min = 2*dx
153 y1 = 0.0
154 y2 = 2.*pi
155 z1 = -rmax*rsph
156 z2 = rmax*rsph
157! CASE(OBLATE_SPHEROIDAL)
158! x2 = RMAX*RSPH/GPAR
159! x2 = LOG(x2+SQRT(x2**2-1.0)) ! = ACOSH(RMAX*RSPH/GPAR)
160! x1 = 2.*x2/(XRES+2) ! x_min = 2*dx
161! y1 = -0.5*PI
162! y2 = 0.5*PI
163 CASE(tancylindrical)
164 x1 = atan(-rmax*rsph/gpar)
165 x2 = atan(rmax*rsph/gpar)
166 y2 = rmax*rsph
167 y1 = 2.*y2 / (yres+2) ! x_min = 2*dx
168 z1 = 0.0
169 z2 = 2.*pi
170! CASE(SINHSPHERICAL)
171! x2 = RMAX*RSPH/GPAR
172! x2 = LOG(x2+SQRT(x2**2+1.0)) ! = ASINH(RMAX*RSPH/GPAR)
173! x1 = 2.*x2/(XRES+2) ! x_min = 2*dx
174! y1 = 0.0
175! y2 = PI
176 CASE DEFAULT
177 CALL sim%Error("InitProgram","geometry not supported for collapse simulation")
178 END SELECT
179
180 ! mesh settings
181 mesh => dict("meshtype" / midpoint, &
182 "geometry" / mgeo, &
183 "inum" / xres, &
184 "jnum" / yres, &
185 "knum" / zres, &
186 "omega" / omega_frame, &
187 "use_fargo"/ 0, &
188 "fargo" / 0, &
189 "xmin" / x1, &
190 "xmax" / x2, &
191 "ymin" / y1, &
192 "ymax" / y2, &
193 "zmin" / z1, &
194 "zmax" / z2, &
195 "output/radius" / 1, &
196 "output/volume" / 1, &
197 "gparam" / gpar)
198 ! mesh settings and boundary conditions
199 SELECT CASE(mgeo)
200 CASE(spherical)
201 bc(west) = reflecting !ABSORBING
202 bc(east) = reflecting !ABSORBING
203 bc(south) = reflecting !AXIS
204 bc(north) = reflecting !AXIS
205 bc(bottom)= periodic
206 bc(top) = periodic
207! sgbc = SPHERMULTEXPAN ! use spherical multipole expansion for BC
208 ! in the multigrid poisson solver
209 CASE(cylindrical)
210 bc(west) = axis !ABSORBING
211 bc(east) = reflecting !ABSORBING
212 bc(south) = periodic
213 bc(north) = periodic
214 bc(bottom)= reflecting
215 bc(top) = reflecting
216! sgbc = CYLINMULTEXPAN ! cylindrical multipole expansion
217! CASE(OBLATE_SPHEROIDAL)
218! bc(WEST) = ABSORBING
219! bc(EAST) = ABSORBING
220! bc(SOUTH) = AXIS
221! bc(NORTH) = AXIS
222! sgbc = CYLINMULTEXPAN ! cylindrical multipole expansion
223 CASE(tancylindrical)
224 bc(west) = reflecting !ABSORBING
225 bc(east) = reflecting !ABSORBING
226 bc(south) = reflecting !AXIS
227 bc(north) = reflecting !NO_GRADIENTS
228 bc(bottom)= periodic
229 bc(top) = periodic
230! sgbc = CYLINMULTEXPAN ! cylindrical multipole expansion
231! CASE(SINHSPHERICAL)
232! bc(WEST) = ABSORBING
233! bc(EAST) = ABSORBING
234! bc(SOUTH) = AXIS
235! bc(NORTH) = AXIS
236! sgbc = SPHERMULTEXPAN ! spherical multipole expansion
237 CASE DEFAULT
238 CALL sim%Error("InitProgram","geometry not supported for collapse simulation")
239 END SELECT
240
241 ! boundary conditions
242 boundary => dict("western" / bc(west), &
243 "eastern" / bc(east), &
244 "southern" / bc(south), &
245 "northern" / bc(north), &
246 "bottomer" / bc(bottom), &
247 "topper" / bc(top))
248
249 ! physics settings
250 physics => dict("problem" / euler, &
251 "gamma" / gamma) ! ratio of specific heats !
252
253 ! compute some derived simulation parameters
254 rho0 = mass / vol0 ! initial density within the spheroid !
255 ! "hydrostatic" pressure * ETA_P
256 ! => with ETA_P approx 100 => free-fall (in case of self-gravity)
257 p0 = 4.0/3.0*pi*gn*rho0**2*rsph**2 / eta_p
258 ! free-fall time (at radius RSPH) with contributions from both
259 ! the selfgravitating spheroid and the central point mass
260 tau = sqrt((rsph**3)/gn/(4./3.*pi*rsph**3*rho0 + centmass))
261
262 ! flux calculation and reconstruction method
263 fluxes => dict("order" / linear, &
264 "fluxtype" / kt, &
265 "variables" / primitive, & ! vars. to use for reconstruction!
266 "limiter" / vanleer, & ! one of: minmod, monocent,... !
267 "theta" / 1.3) ! optional parameter for limiter !
268
269 ! source term due to a point mass
270 pmass => dict("gtype" / pointmass, & ! grav. accel. of a point mass !
271 "mass" / centmass) ! mass [kg] !
272
273 ! source term due to self-gravity
274! selfgravity => Dict( &
275! "gtype" / SPECTRAL)!, & ! poisson solver for self-gravity!
276! "gtype" / MULTIGRID, & ! poisson solver for self-gravity!
277! "maxmult" / 5, & ! number of (spher.) multipol moments
278! "maxresidnorm" / 1.0E-7, & ! accuracy of multigrid solver (max error)
279! "relaxtype" / BLOCK_GAUSS_SEIDEL, & ! relaxation method
280! "relaxtype" / RED_BLACK_GAUSS_SEIDEL, &
281! "relaxtype" / GAUSS_SEIDEL, &
282! "npre" / 1, & ! number of pre smoothings
283! "npost" / 1, & ! and post smoothings
284! "minres" / 3, & ! resolution of coarsest grid
285! "nmaxcycle" / 250, & ! limit for iterations
286! "bndrytype" / sgbc) ! multipole expansion (see above)
287
288 ! enable gravity
289 grav => dict("stype" / gravity, &
290 "point" / pmass)
291! CALL SetAttr(grav, "self", selfgravity) ! currently not supported because the multigird solver is not working
292
293 ! initialize source term with gravitz module
294 sources => dict("grav" / grav)
295
296 ! check for rotating frame
297 IF (omega_frame.GT.tiny(omega_frame)) THEN
298 rotframe => dict("stype" / rotating_frame, &
299 "x" / 0.0, &
300 "y" / 0.0)
301 CALL setattr(sources, "rotframe", rotframe)
302 END IF
303
304
305 ! time discretization settings
306 timedisc => dict( &
307 "method" / modified_euler, &
308 "order" / 3, &
309 "cfl" / 0.4, &
310 "stoptime" / (tsim * tau), &
311 "dtlimit" / 1.0e-9, &
312 "rhstype" / 1, &
313 "maxiter" / 10000000)
314
315 ! initialize data input/output
316 datafile => dict( &
317 "fileformat" / vtk, &
318! "fileformat" / XDMF, &
319 "filename" / (trim(odir) // trim(ofname)), &
320 "count" / onum)
321
322 config => dict("mesh" / mesh, &
323 "physics" / physics, &
324 "boundary" / boundary, &
325 "fluxes" / fluxes, &
326 "timedisc" / timedisc, &
327 "sources" / sources, &
328 "datafile" / datafile)
329 END SUBROUTINE makeconfig
330
331
332 SUBROUTINE initdata(Mesh,Physics,Timedisc)
333 IMPLICIT NONE
334 !------------------------------------------------------------------------!
335 CLASS(mesh_base) :: Mesh
336 CLASS(physics_base) :: Physics
337 CLASS(timedisc_base):: Timedisc
338 !------------------------------------------------------------------------!
339 CHARACTER(LEN=64) :: value
340 INTEGER :: i,j,k
341 TYPE(marray_base) :: ez,posvec
342 !------------------------------------------------------------------------!
343 INTENT(IN) :: mesh,physics
344 INTENT(INOUT) :: timedisc
345 !------------------------------------------------------------------------!
346 ! compute curvilinear components of vertical unit vector e_z
347 ez = marray_base(3)
348 ! set cartesian components
349 ez%data2d(:,1:2) = 0.0
350 ez%data2d(:,3) = 1.0
351 ! convert to curvilinear components
352 CALL mesh%geometry%Convert2Curvilinear(mesh%bcenter,ez%data4d,ez%data4d)
353
354 ! bary center position vector
355 posvec = marray_base(3)
356 posvec%data4d = mesh%posvec%bcenter
357
358 SELECT TYPE(pvar => timedisc%pvar)
359 TYPE IS(statevector_euler) ! non-isothermal HD
360 ! density
361 WHERE (mesh%radius%data2d(:,2).LE.rsph) ! bary center values collapsed to data1d
362 pvar%density%data1d(:) = rho0
363 ELSEWHERE
364 pvar%density%data1d(:) = rho0 * eta_rho
365 END WHERE
366 ! velocities
367 pvar%velocity = (omega-omega_frame) * (ez.x.posvec)
368 ! pressure
369 pvar%pressure%data1d(:) = p0
370 CLASS DEFAULT
371 CALL sim%Error("collapse::InitData","physics not supported in this setup")
372 END SELECT
373
374 CALL physics%Convert2Conservative(timedisc%pvar,timedisc%cvar)
375
376 CALL mesh%Info(" DATA-----> initial condition: " // &
377 "Homogenious density with uniform angular frequency")
378 IF (centmass.GT.tiny(centmass)) THEN
379 WRITE (value,"(E12.4)") sqrt(rsph**3/(centmass*physics%constants%GN))
380 CALL mesh%Info(" " // &
381 "timescale of pointmass: " //trim(value))
382 END IF
383 IF (mass .GT. tiny(mass)) THEN
384 WRITE(value,"(E12.4)") sqrt(3.0*pi/(4.0*rho0*physics%constants%GN))
385 CALL mesh%Info(" " // &
386 "timescale of self-gravity: " //trim(value))
387 END IF
388 IF (omega .GT. tiny(omega)) THEN
389 WRITE (value,"(E12.4)") omega
390 CALL mesh%Info(" " // &
391 "angular velocity: " // trim(value))
392 END IF
393
394 WRITE (value,"(E12.4)") tau
395 CALL mesh%Info(" " // &
396 "free-fall time: " //trim(value))
397
398 SELECT TYPE(bwest => timedisc%Boundary%Boundary(west)%p)
399 CLASS IS(boundary_custom)
400 IF(mgeo.EQ.spherical) THEN
401 CALL bwest%SetCustomBoundaries(mesh,physics, &
402 (/custom_nograd,custom_reflect,custom_reflect,custom_fixed,custom_reflect/))
403 bwest%data(:,:,:,physics%ZVELOCITY) = 0.0
404 ELSE IF(mgeo.EQ.cylindrical) THEN
405 CALL bwest%SetCustomBoundaries(mesh,physics, &
406! (/CUSTOM_NOGRAD,CUSTOM_REFLECT,CUSTOM_FIXED,CUSTOM_REFLECT/))
407 (/custom_nograd,custom_reflect,custom_fixed,custom_nograd,custom_reflect/))
408 bwest%data(:,:,:,physics%YVELOCITY) = 0.0
409 END IF
410 END SELECT
411
412 SELECT TYPE(bbottom => timedisc%Boundary%Boundary(bottom)%p)
413 CLASS IS(boundary_fixed)
414 IF(mgeo.EQ.cylindrical) THEN
415 bbottom%fixed(:,:,:) = .true.
416 bbottom%data(:,:,1,:) = timedisc%pvar%data4d(:,:,mesh%KMIN,:)
417 bbottom%data(:,:,2,:) = timedisc%pvar%data4d(:,:,mesh%KMIN,:)
418 END IF
419 CLASS IS(boundary_farfield)
420 bbottom%data(:,:,1,:) = timedisc%pvar%data4d(:,:,mesh%KMIN,:)
421 bbottom%data(:,:,2,:) = timedisc%pvar%data4d(:,:,mesh%KMIN,:)
422 END SELECT
423
424 SELECT TYPE(btop => timedisc%Boundary%Boundary(top)%p)
425 CLASS IS(boundary_fixed)
426 IF(mgeo.EQ.cylindrical) THEN
427 btop%fixed(:,:,:) = .true.
428 btop%data(:,:,1,:) = timedisc%pvar%data4d(:,:,mesh%KMAX,:)
429 btop%data(:,:,2,:) = timedisc%pvar%data4d(:,:,mesh%KMAX,:)
430 END IF
431 CLASS IS(boundary_farfield)
432 btop%data(:,:,1,:) = timedisc%pvar%data4d(:,:,mesh%KMAX,:)
433 btop%data(:,:,2,:) = timedisc%pvar%data4d(:,:,mesh%KMAX,:)
434 END SELECT
435
436 END SUBROUTINE initdata
437
438END PROGRAM collapse
439
subroutine initdata(Mesh, Physics, Fluxes, Timedisc)
Definition: bondi2d.f90:274
subroutine makeconfig(Sim, config)
Definition: bondi2d.f90:165
program collapse
Definition: collapse.f90:43
pure real function, dimension(size(ephir%data2d, dim=1)) omega(ephir, velocity)
main fosite class
Definition: fosite.f90:71