MPI-AMRVAC 3.1
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_random_heating.t
Go to the documentation of this file.
3 use mod_comm_lib, only: mpistop
4 double precision, allocatable :: va1(:),ta1(:),tb1(:),va2(:),ta2(:),tb2(:)
5 !> This module is for imposing randomized heating at x-axis for 2.5D simulation, for details please see Zhou et al. (2020, Nature Astronomy,4,994) and
6 !> Li et al. (2022,ApJ,926,216).
7 !> Users can define the parameters "trelax,vtim,vlim,periods,variation,num,mnx" in the mod_usr.t file.
8 !> Example for using this module please see tests/mhd/coronal_rain_2.5D
9 !trelax is the relaxization time for the simulation, if the relaxization is done seperately, then trelax=0.d0
10 !periods=300,variation=75 !The time durations of each heating episode is typically 300s +/- 75s
11 !vtim = 100 !100 heating episodes, e.g., 500 min. Enough for the simulation
12 !num = 1000 !1000 waves for each episode
13 !si=5./6. !spectral index
14 !mnx could be chosen as twice of the spatial resolution in the simulation
15 !vlim could be chosen as the same with mnx
16
17contains
18
19 subroutine getlqgrid(lQgrid,ixI^L,ixO^L,qt,trelax,x,mode,vtim,vlim)
21 integer, intent(in) :: ixI^L, ixO^L, mode, vtim, vlim
22 double precision, intent(in) :: qt, trelax, x(ixI^S,1:ndim)
23 double precision, intent(inout) :: lQgrid(ixI^S)
24
25 double precision :: tl1,tl2,tl3,tl4,tl5,tl6,t2,stt
26 double precision :: tr1,tr2,tr3,tr4,tr5,tr6
27 double precision :: va0
28 integer :: Bp,Bt1,Bt2,ix^D,i
29
30 t2 = qt - trelax
31 va0=0.4d0
32 stt = (xprobmax1- xprobmin1) / (dble(vlim) - 1.d0)
33
34 select case(mode)
35 ! mode 1 for gaussian, mode 2 for sinc
36 case(1)
37 if(qt .lt. trelax) then
38 lqgrid(ixo^s)=0.d0
39 else
40 do i = 4, vtim
41 if(qt .lt. trelax + tb1(i)) then
42 tl1 = dexp(-(t2 - tb1(i-3))**2/(0.5d0*ta1(i-3))**2)
43 tl2 = dexp(-(t2 - tb1(i-2))**2/(0.5d0*ta1(i-2))**2)
44 tl3 = dexp(-(t2 - tb1(i-1))**2/(0.5d0*ta1(i-1))**2)
45 tl4 = dexp(-(t2 - tb1(i))**2/(0.5d0*ta1(i))**2)
46 tl5 = dexp(-(t2 - tb1(i+1))**2/(0.5d0*ta1(i+1))**2)
47 tl6 = dexp(-(t2 - tb1(i+2))**2/(0.5d0*ta1(i+2))**2)
48 {do ix^db = ixomin^db,ixomax^db\}
49 bp = floor((x(ix^d,1) - xprobmin1) / stt) + 1
50 if (bp .lt. 1) bp=1
51 if(x(ix^d,1) .lt. 0.d0) then
52 lqgrid(ix^d) = tl1 * (va1(bp + (i-4)*vlim)*(one-va0)+va0) &
53 + tl2 * (va1(bp + (i-3)*vlim)*(one-va0)+va0) &
54 + tl3 * (va1(bp + (i-2)*vlim)*(one-va0)+va0) &
55 + tl4 * (va1(bp + (i-1)*vlim)*(one-va0)+va0) &
56 + tl5 * (va1(bp + (i)*vlim)*(one-va0)+va0) &
57 + tl6 * (va1(bp + (i+1)*vlim)*(one-va0)+va0)
58 endif
59 {enddo\}
60 exit
61 endif
62 enddo
63
64 do i = 4, vtim
65 if(qt .lt. trelax + tb2(i)) then
66 tr1 = dexp(-(t2 - tb2(i-3))**2/(0.5d0*ta2(i-3))**2)
67 tr2 = dexp(-(t2 - tb2(i-2))**2/(0.5d0*ta2(i-2))**2)
68 tr3 = dexp(-(t2 - tb2(i-1))**2/(0.5d0*ta2(i-1))**2)
69 tr4 = dexp(-(t2 - tb2(i))**2/(0.5d0*ta2(i))**2)
70 tr5 = dexp(-(t2 - tb2(i+1))**2/(0.5d0*ta2(i+1))**2)
71 tr6 = dexp(-(t2 - tb2(i+2))**2/(0.5d0*ta2(i+2))**2)
72 {do ix^db = ixomin^db,ixomax^db\}
73 bp = floor((x(ix^d,1) - xprobmin1) / stt) + 1
74 if (bp .lt. 1) bp=1
75 if(x(ix^d,1) .ge. 0.d0) then
76 lqgrid(ix^d) = tr1 * (va2(bp + (i-4)*vlim)*(one-va0)+va0) &
77 + tr2 * (va2(bp + (i-3)*vlim)*(one-va0)+va0) &
78 + tr3 * (va2(bp + (i-2)*vlim)*(one-va0)+va0) &
79 + tr4 * (va2(bp + (i-1)*vlim)*(one-va0)+va0) &
80 + tr5 * (va2(bp + (i)*vlim)*(one-va0)+va0) &
81 + tr6 * (va2(bp + (i+1)*vlim)*(one-va0)+va0)
82 endif
83 {enddo\}
84 exit
85 endif
86 enddo
87 endif
88 case(2)
89 if(qt .lt. trelax) then
90 tr1 = 0.d0
91 tr3 = 0.d0
92 bt1 = 0
93 else if(qt .lt. trelax + tb1(1)) then
94 tr1 = dsin(t2 * dpi / tb1(2))
95 tr3 = 0.d0
96 bt1 = 0
97 else if(qt .lt. trelax + tb1(2)) then
98 tr1 = dsin(t2 * dpi / tb1(2))
99 tr3 = dsin((t2 - tb1(1)) * dpi / (tb1(3) - tb1(1)))
100 bt1 = 0
101 else
102 do i = 2, vtim
103 if(t2 .lt. tb1(i)) then
104 bt1 = i - 1
105 exit
106 endif
107 enddo
108 tr1 = dsin((t2 - tb1(bt1-1)) * dpi / (tb1(bt1+1) - tb1(bt1-1)))
109 tr3 = dsin((t2 - tb1(bt1)) * dpi / (tb1(bt1+2) - tb1(bt1)))
110 endif
111 if(qt .lt. trelax) then
112 tr2 = 0.d0
113 tr4 = 0.d0
114 bt2 = 0
115 else if(qt .lt. trelax + tb2(1)) then
116 tr2 = dsin(t2 * dpi / tb2(2))
117 tr4 = 0.d0
118 bt2 = 0
119 else if(qt .lt. trelax + tb2(2)) then
120 tr1 = dsin(t2 * dpi / tb2(2))
121 tr3 = dsin((t2 - tb2(1)) * dpi / (tb2(3) - tb2(1)))
122 bt2 = 0
123 else
124 do i = 2, vtim
125 if(t2 .lt. tb2(i)) then
126 bt2 = i - 1
127 exit
128 endif
129 enddo
130 tr2 = dsin((t2 - tb2(bt2-1)) * dpi / (tb2(bt2+1) - tb2(bt2-1)))
131 tr4 = dsin((t2 - tb2(bt2)) * dpi / (tb2(bt2+2) - tb2(bt2)))
132 endif
133 {do ix^db = ixomin^db,ixomax^db\}
134 bp = floor((x(ix^d,1) - xprobmin1) / stt) + 1
135 if(x(ix^d,1) .lt. 0.d0) then
136 lqgrid(ix^d) = tr1 * (va1(bp + bt1*vlim)*(one-va0)+va0) + tr3 * (va1(bp+(bt1+1)*vlim)*(one-va0)+va0)
137 else
138 lqgrid(ix^d) = tr2 * (va2(bp + bt2*vlim)*(one-va0)+va0) + tr4 * (va2(bp+(bt2+1)*vlim)*(one-va0)+va0)
139 endif
140 {enddo\}
141 case default
142 call mpistop('unknow mode')
143 end select
144
145 end subroutine getlqgrid
146
147 subroutine generatetv(vtim,vlim,periods,variation,mnx,num,si)
148 integer, intent(in) :: vtim,vlim,mnx,num
149 double precision, intent(in) :: periods,variation,si
150 integer :: i,vx,j
151 logical :: alive
152 character(len=100) :: filename
153
154 ! generate random T, typically 300s +/- 75s
155
156 allocate(ta1(vtim)) ! left footpoint
157 allocate(tb1(vtim))
158 allocate(ta2(vtim)) ! right footpoint
159 allocate(tb2(vtim))
160
161 if (ndim/=2) call mpistop("Randomized heating for 2D, 2.5D simulations only!")
162 if (mype==0) then
163 write(filename,"(a)") "LeftT.dat"
164 inquire(file=filename,exist=alive)
165 if(alive) then
166 open(unit=21,file=filename,status='old')
167 do j=1,vtim
168 read(21,*) tb1(j)
169 enddo
170 close(21)
171 else
172 call randomt(tb1,vtim,periods,variation,filename)
173 endif
174
175 write(filename,"(a)") "RightT.dat"
176 inquire(file=filename,exist=alive)
177 if(alive) then
178 open(unit=21,file=filename,status='old')
179 do j=1,vtim
180 read(21,*) tb2(j)
181 enddo
182 close(21)
183 else
184 call randomt(tb2,vtim,periods,variation,filename)
185 endif
186
187 ta1 = tb1
188 ta2 = tb2
189 do i = 2, vtim
190 ta1(i) = tb1(i) - tb1(i-1)
191 ta2(i) = tb2(i) - tb2(i-1)
192 enddo
193 endif
194 call mpi_barrier(icomm,ierrmpi)
195 if (npe>1) then
196 call mpi_bcast(tb1,vtim,mpi_double_precision,0,icomm,ierrmpi)
197 call mpi_bcast(ta1,vtim,mpi_double_precision,0,icomm,ierrmpi)
198 call mpi_bcast(tb2,vtim,mpi_double_precision,0,icomm,ierrmpi)
199 call mpi_bcast(ta2,vtim,mpi_double_precision,0,icomm,ierrmpi)
200 endif
201
202 ! spatial distribution
203
204 vx=vtim*vlim
205 allocate(va1(vx))
206 allocate(va2(vx))
207 if (mype==0) then
208 write(filename,"(a)") "LeftV.dat"
209 inquire(file=filename,exist=alive)
210 if(alive) then
211 open(unit=22,file=filename,status='old')
212 do j=1,vx
213 read(22,*) va1(j)
214 enddo
215 close(22)
216 else
217 call randomv(va1,vtim,vlim,mnx,num,si,filename)
218 endif
219
220 write(filename,"(a)") "RightV.dat"
221 inquire(file=filename,exist=alive)
222 if(alive) then
223 open(unit=22,file=filename,status='old')
224 do j=1,vx
225 read(22,*) va2(j)
226 enddo
227 close(22)
228 else
229 call randomv(va2,vtim,vlim,mnx,num,si,filename)
230 endif
231 endif
232 if (npe>1) then
233 call mpi_bcast(va1,vx,mpi_double_precision,0,icomm,ierrmpi)
234 call mpi_bcast(va2,vx,mpi_double_precision,0,icomm,ierrmpi)
235 endif
236
237 end subroutine generatetv
238
239
240 subroutine randomt(tb,vtim,periods,variation,filename)
241 integer, intent(in) :: vtim
242 double precision, intent(in) :: periods,variation
243 double precision, intent(inout) :: tb(:)
244 character(len=100), intent(in) :: filename
245 double precision :: tt1,tt,mm
246 integer :: i
247
248 ! generate random T, typically 300s +/- 75s
249
250 tt = 0.d0
251 do i = 1, vtim
252 call random_number(mm)
253 tt1 = periods + variation * 2. * (mm - 0.5)
254 tt = tt + tt1
255 tb(i) = tt / unit_time
256 end do
257
258 open(unit=21,file=filename,form='formatted',status='new')
259 write(21,'(es12.4)') tb
260 close(21)
261
262 end subroutine randomt
263
264 subroutine randomv(va,vtim,vlim,mnx,num,si,filename)
265 integer, intent(in) :: vtim,vlim,mnx,num
266 double precision, intent(in) :: si
267 double precision, intent(inout) :: va(:)
268 character(len=100), intent(in) :: filename
269 double precision, allocatable :: vn(:,:),vm(:)
270 double precision :: lambda,c,lambda_min,lambda_max,rms,ll
271 integer :: i
272 integer :: j, kk, lth = 1
273
274 allocate(vn(num, mnx))
275 allocate(vm(mnx))
276 do kk = 1, vtim
277 lambda_min = lth * 1.d0 / (mnx * 1.d0)
278 lambda_max = lth * 2.d0
279 do i = 1, num
280 lambda = i * 1.d0 / num * (lambda_max - lambda_min) + lambda_min
281 c = lambda ** si
282 call random_number(ll)
283 do j = 1, mnx
284 vn(i,j) = c*sin(2.*dpi*(j*1.d0/(mnx-1)*lth)/lambda+2.*dpi*2.*(ll-0.5))
285 end do
286 end do
287 rms = 0.d0
288 vm = 0.d0
289 do j = 1, mnx
290 do i = 1, num
291 vm(j) = vm(j) + vn(i, j)
292 end do
293 rms = rms + vm(j)**2
294 end do
295 vm = vm / dsqrt(rms/mnx) ! normalization
296 do j = 1, vlim
297 va(vlim*(kk-1)+j) = vm(j)**2
298 end do
299 end do
300
301 open(unit=22,file=filename,form='formatted',status='new')
302 write(22,'(es12.4)') va
303 close(22)
304
305 end subroutine randomv
306
307end module mod_random_heating
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision, dimension(:), allocatable va2
double precision, dimension(:), allocatable tb1
double precision, dimension(:), allocatable ta2
double precision, dimension(:), allocatable ta1
double precision, dimension(:), allocatable va1
subroutine generatetv(vtim, vlim, periods, variation, mnx, num, si)
subroutine getlqgrid(lqgrid, ixil, ixol, qt, trelax, x, mode, vtim, vlim)
This module is for imposing randomized heating at x-axis for 2.5D simulation, for details please see ...
subroutine randomv(va, vtim, vlim, mnx, num, si, filename)
double precision, dimension(:), allocatable tb2
subroutine randomt(tb, vtim, periods, variation, filename)