sources_cooling.f90
Go to the documentation of this file.
1!#############################################################################
2!# #
3!# fosite - 3D hydrodynamical simulation program #
4!# module: sources_cooling.f90 #
5!# #
6!# Copyright (C) 2009-2024 #
7!# Tobias Illenseer <tillense@astrophysik.uni-kiel.de> #
8!# #
9!# This program is free software; you can redistribute it and/or modify #
10!# it under the terms of the GNU General Public License as published by #
11!# the Free Software Foundation; either version 2 of the License, or (at #
12!# your option) any later version. #
13!# #
14!# This program is distributed in the hope that it will be useful, but #
15!# WITHOUT ANY WARRANTY; without even the implied warranty of #
16!# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or #
17!# NON INFRINGEMENT. See the GNU General Public License for more #
18!# details. #
19!# #
20!# You should have received a copy of the GNU General Public License #
21!# along with this program; if not, write to the Free Software #
22!# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #
23!# #
24!#############################################################################
25!----------------------------------------------------------------------------!
32!----------------------------------------------------------------------------!
39!----------------------------------------------------------------------------!
49 USE common_dict
50 IMPLICIT NONE
51 !--------------------------------------------------------------------------!
52 PRIVATE
53 CHARACTER(LEN=32), PARAMETER :: source_name = "optically thin cooling"
54 !--------------------------------------------------------------------------!
55 TYPE, EXTENDS(sources_base) :: sources_cooling
56 TYPE(marray_base), ALLOCATABLE :: q
57 REAL :: switchon
58 REAL :: tmin
59 CONTAINS
60 PROCEDURE :: initsources
61 PROCEDURE :: setoutput
62 PROCEDURE :: externalsources
63 PROCEDURE :: calctimestep
64 PROCEDURE :: updatecooling
65 final :: finalize
66 END TYPE
67
68 !--------------------------------------------------------------------------!
69 PUBLIC :: &
70 ! types
72 !--------------------------------------------------------------------------!
73
74CONTAINS
75
76 SUBROUTINE initsources(this,Mesh,Physics,Fluxes,config,IO)
78 IMPLICIT NONE
79 !------------------------------------------------------------------------!
80 CLASS(sources_cooling), INTENT(INOUT) :: this
81 CLASS(mesh_base), INTENT(IN) :: Mesh
82 CLASS(physics_base), INTENT(IN) :: Physics
83 CLASS(fluxes_base), INTENT(IN) :: Fluxes
84 TYPE(dict_typ), POINTER :: config,IO
85 !------------------------------------------------------------------------!
86 INTEGER :: stype,err
87 !------------------------------------------------------------------------!
88 CALL getattr(config, "stype", stype)
89 ! call basic initialization subroutine
90 CALL this%InitSources_base(stype,source_name)
91
92 ! Courant number, i.e. safety factor for numerical stability
93 CALL getattr(config, "cvis", this%cvis, 0.1)
94
95 ! minimum temperature
96 CALL getattr(config, "Tmin", this%Tmin, 1.0e-30)
97
98 ! soft switch on time scale for activating cooling (negative disables)
99 CALL getattr(config, "switchon", this%switchon, -1.0)
100
101 ! some sanity checks
102 ! isothermal modules are excluded
103 SELECT TYPE (phys => physics)
104 CLASS IS(physics_euler)
105 ! do nothing
106 CLASS DEFAULT
107 ! abort
108 CALL this%Error("sources_cooling::InitSources","physics not supported")
109 END SELECT
110
111 ALLOCATE(this%Q,stat=err)
112 IF (err.NE.0) CALL this%Error("sources_cooling::InitSources","memory allocation failed")
113 this%Q = marray_base()
114
115 ! set initial time < 0
116 this%time = -1.0
117
118 ! initialize cooling function
119 this%Q%data1d(:) = 0.0
120
121 ! register ouput arrays
122 CALL this%SetOutput(mesh,config,io)
123 END SUBROUTINE initsources
124
125
126 SUBROUTINE setoutput(this,Mesh,config,IO)
127 IMPLICIT NONE
128 !------------------------------------------------------------------------!
129 CLASS(sources_cooling), INTENT(INOUT) :: this
130 CLASS(mesh_base), INTENT(IN) :: Mesh
131 TYPE(dict_typ), POINTER :: config,IO
132 !------------------------------------------------------------------------!
133 INTEGER :: valwrite
134 !------------------------------------------------------------------------!
135 ! register cooling term for output
136 CALL getattr(config, "output/Qcool", valwrite, 0)
137 IF (valwrite .EQ. 1) &
138 CALL setattr(io, "Qcool", &
139 this%Q%data3d(mesh%IMIN:mesh%IMAX,mesh%JMIN:mesh%JMAX,mesh%KMIN:mesh%KMAX))
140 END SUBROUTINE setoutput
141
142
143 SUBROUTINE externalsources(this,Mesh,Physics,Fluxes,Sources,time,dt,pvar,cvar,sterm)
145 IMPLICIT NONE
146 !------------------------------------------------------------------------!
147 CLASS(sources_cooling), INTENT(INOUT) :: this
148 CLASS(mesh_base),INTENT(IN) :: Mesh
149 CLASS(physics_base),INTENT(INOUT) :: Physics
150 CLASS(sources_base),INTENT(INOUT) :: Sources
151 CLASS(fluxes_base),INTENT(IN) :: Fluxes
152 REAL,INTENT(IN) :: time, dt
153 CLASS(marray_compound),INTENT(INOUT):: pvar,cvar,sterm
154 !------------------------------------------------------------------------!
155 SELECT TYPE(s => sterm)
156 TYPE IS (statevector_euler)
157 s%density%data1d(:) = 0.0
158 s%momentum%data1d(:) = 0.0
159
160 SELECT TYPE(phys => physics)
161 TYPE IS (physics_euler)
162 SELECT TYPE(p => pvar)
163 TYPE IS (statevector_euler)
164 CALL this%UpdateCooling(mesh,phys,time,p)
165 END SELECT
166 END SELECT
167
168 ! energy loss due to radiation processes
169 s%energy%data1d(:) = -this%Q%data1d(:)
170
171 END SELECT
172 END SUBROUTINE externalsources
173
174
179 SUBROUTINE calctimestep(this,Mesh,Physics,Fluxes,pvar,cvar,time,dt,dtcause)
181 IMPLICIT NONE
182 !------------------------------------------------------------------------!
183 CLASS(sources_cooling), INTENT(INOUT) :: this
184 CLASS(mesh_base), INTENT(IN) :: Mesh
185 CLASS(physics_base), INTENT(INOUT) :: Physics
186 CLASS(fluxes_base), INTENT(IN) :: Fluxes
187 CLASS(marray_compound), INTENT(INOUT) :: pvar,cvar
188 REAL, INTENT(IN) :: time
189 REAL, INTENT(INOUT) :: dt
190 INTEGER, INTENT(OUT) :: dtcause
191 !------------------------------------------------------------------------!
192 REAL :: invdt
193 !------------------------------------------------------------------------!
194 ! maximum of inverse cooling timescale t_cool ~ P/Q_cool
195 dt = huge(invdt)
196 SELECT TYPE(p => pvar)
197 CLASS IS(statevector_euler)
198 SELECT TYPE(phys => physics)
199 TYPE IS (physics_euler)
200 SELECT TYPE(p => pvar)
201 TYPE IS (statevector_euler)
202 CALL this%UpdateCooling(mesh,phys,time,p)
203 invdt = maxval(abs(this%Q%data1d(:) / p%pressure%data1d(:)), &
204 mask=mesh%without_ghost_zones%mask1d(:))
205 IF (invdt.GT.tiny(invdt)) dt = this%cvis / invdt
206 END SELECT
207 END SELECT
208 END SELECT
209 END SUBROUTINE calctimestep
210
211
213 SUBROUTINE updatecooling(this,Mesh,Physics,time,pvar)
215 IMPLICIT NONE
216 !------------------------------------------------------------------------!
217 CLASS(sources_cooling), INTENT(INOUT) :: this
218 CLASS(mesh_base), INTENT(IN) :: Mesh
219 CLASS(physics_euler), INTENT(IN) :: Physics
220 REAL, INTENT(IN) :: time
221 CLASS(statevector_euler), INTENT(IN) :: pvar
222 !------------------------------------------------------------------------!
223 REAL :: muRgamma,Namu,scaling
224 !------------------------------------------------------------------------!
225 SELECT TYPE(p => pvar)
226 CLASS IS(statevector_euler)
227 ! modify Qcool during switchon phase
228 IF (time.GE.0.0.AND.time.LE.this%switchon) THEN
229 ! compute new scaling factor < 1 during switchon phase
230 scaling = sin(0.5*pi*time/this%switchon)**2
231 ELSE
232 scaling = 1.0
233 END IF
234 ! conversion factor cs2 -> T / Kelvin
235 murgamma = physics%mu /(physics%Constants%RG*physics%gamma) &
236 / physics%Constants%cf_temperature
237 ! conversion factor mass density -> particle density / m^3
238 namu = physics%Constants%NA/physics%mu &
239 / physics%Constants%cf_density * physics%Constants%cf_mass
240 ! compute cooling source term ~ n^2 * Λ(T) with
241 ! particle density n / m^3 and temperature T / K
242 ! return value of lambda is given SI units i.e. W/m^3
243 WHERE (mesh%without_ghost_zones%mask1d(:))
244 this%Q%data1d(:) = scaling * physics%Constants%cf_energy &
245 * (namu * p%density%data1d(:))**2 &
246 * lambda(murgamma * physics%bccsound%data1d(:)**2)
247 ELSEWHERE
248 this%Q%data1d(:) = 0.0
249 END WHERE
250 END SELECT
251 END SUBROUTINE updatecooling
252
253
256 ELEMENTAL FUNCTION lambda(T) RESULT(L)
257 IMPLICIT NONE
258 REAL, INTENT(IN) :: t
259 REAL :: l
260 IF (t.LT.1.26e+4) THEN
261 ! disable cooling for T < 1.26e4 K, i.e. set L to 0
262 ! this is a very very rough approximation
263 ! dont't trust this function for T < 1.26e4 !!!
264 l = 0.0
265 ELSE IF ((t.GE.1.26e+4).AND.(t.LT.1.5e+5)) THEN
266 l = 3.7d-38 * exp(0.58*log(t))
267 ELSE IF ((t.GE.1.5e5).AND.(t.LT.2.2e+7)) THEN
268 l = 1.2d-31 * exp(-0.68*log(t))
269 ELSE
270 l = 1.2d-39 * exp(0.41*log(t))
271 END IF
272 END FUNCTION lambda
273
274
275 SUBROUTINE finalize(this)
276 IMPLICIT NONE
277 !------------------------------------------------------------------------!
278 TYPE(sources_cooling), INTENT(INOUT) :: this
279 !------------------------------------------------------------------------!
280 DEALLOCATE(this%Q)
281 END SUBROUTINE finalize
282
283END MODULE sources_cooling_mod
Dictionary for generic data types.
Definition: common_dict.f90:61
base module for numerical flux functions
Definition: fluxes_base.f90:39
Basic fosite module.
subroutine finalize(this)
Destructor of logging_base class.
base class for mesh arrays
Definition: marray_base.f90:36
derived class for compound of mesh arrays
basic mesh module
Definition: mesh_base.f90:72
subroutine setoutput(this, config, IO)
Setup mesh fields for i/o.
Definition: mesh_base.f90:828
Basic physics module.
physics module for 1D,2D and 3D non-isothermal Euler equations
generic source terms module providing functionaly common to all source terms
source terms module for constant acceleration
character(len=32), parameter source_name
subroutine calctimestep(this, Mesh, Physics, Fluxes, pvar, cvar, time, dt, dtcause)
subroutine externalsources(this, Mesh, Physics, Fluxes, Sources, time, dt, pvar, cvar, sterm)
subroutine initsources(this, Mesh, Physics, Fluxes, config, IO)
source terms module for simple optically thin cooling
subroutine updatecooling(this, Mesh, Physics, time, pvar)
Updates the cooling function at each time step.
elemental real function lambda(T)
simple optically thin cooling function ATTENTION: input data should be in SI-units,...
basic mesh array class
Definition: marray_base.f90:69
mesh data structure
Definition: mesh_base.f90:122