MPI-AMRVAC 3.1
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_random_heating_3D.t
Go to the documentation of this file.
3 use mod_comm_lib, only: mpistop
4
5 double precision, allocatable :: va^d(:)
6 double precision, allocatable :: dtimearr(:),timearray(:)
7 ! This module is for imposing randomized heating in any-D setup
8 ! Users can define the parameters "trelax,tramp,ntimes,vlim^D,periods,variation,nwaves" in the mod_usr.t file.
9 !periods=300,variation=75 The time durations in seconds of each heating episode is typically 300s +/- 75s
10 !ntimes = 100 100 heating episodes, e.g., 500 min. Enough for the simulation
11 !nwaves = 1000 1000 waves for each episode
12 !si=5./6. spectral index
13 !vlim^D could be chosen as twice of the maximal spatial resolution in the simulation
14
15contains
16
17 subroutine getlqgrid(lQgrid,ixI^L,ixO^L,qt,trelax,tramp,x,ntimes,vlim^D)
19 use mod_geometry
20 integer, intent(in) :: ixI^L, ixO^L, ntimes, vlim^D
21 double precision, intent(in) :: qt, trelax, tramp,x(ixI^S,1:ndim)
22 double precision, intent(inout) :: lQgrid(ixI^S)
23
24 double precision :: xcar(ixI^S,1:ndim)
25 double precision :: tshift,tr,stt^D,xcarmin^D
26 double precision :: tl1,tl2,tl3,tl4,tl5,tl6
27 double precision :: pulse1,pulse2,pulse3,pulse4,pulse5,pulse6
28 integer :: iip^D,ix^D,i
29
30 tshift = qt - trelax
31
32 if(qt .lt. trelax) then
33 tr=zero
34 elseif(qt .lt. trelax+tramp) then
35 tr=(qt-trelax)/tramp
36 else
37 tr=one
38 endif
39
40
41 do i = 4, ntimes
42 if(qt .lt. trelax + timearray(i)) then
43 tl1 = dexp(-(tshift - timearray(i-3))**2/(0.5d0*dtimearr(i-3))**2)
44 tl2 = dexp(-(tshift - timearray(i-2))**2/(0.5d0*dtimearr(i-2))**2)
45 tl3 = dexp(-(tshift - timearray(i-1))**2/(0.5d0*dtimearr(i-1))**2)
46 tl4 = dexp(-(tshift - timearray(i) )**2/(0.5d0*dtimearr(i) )**2)
47 tl5 = dexp(-(tshift - timearray(i+1))**2/(0.5d0*dtimearr(i+1))**2)
48 tl6 = dexp(-(tshift - timearray(i+2))**2/(0.5d0*dtimearr(i+2))**2)
49 {do ix^db = ixomin^db,ixomax^db\}
50 select case(coordinate)
51 case (cartesian)
52 ! remapped on the unit cube
53 ^d&stt^d=(xprobmax^d-xprobmin^d)/(dble(vlim^d)-1.d0);
54 ^d&iip^d=floor((x(ix^dd,^d)-xprobmin^d)/stt^d)+1;
55 ^d&iip^d=max(1,iip^d);
56 case (cylindrical)
57 {^iftwod
58 call mpistop("random_heating_3D to be adjusted for 2D cylindrical")
59 }
60 {^ifthreed
61 ! from R-Z-phi to x-y-z
62 xcar(ix1,ix2,ix3,1)=x(ix1,ix2,ix3,r_)*dcos(x(ix1,ix2,ix3,phi_))
63 xcar(ix1,ix2,ix3,2)=x(ix1,ix2,ix3,r_)*dsin(x(ix1,ix2,ix3,phi_))
64 xcar(ix1,ix2,ix3,3)=x(ix1,ix2,ix3,z_)
65 ! minimal coordinate x-y-z from Rmax and Z-range
66 xcarmin1=-xprobmax1
67 xcarmin2=-xprobmax1
68 xcarmin3=xprobmin2
69 ! x-coordinate between -Rmax,+Rmax
70 stt1=(2.0d0*xprobmax1)/(dble(vlim1)-1.d0)
71 ! y-coordinate between -Rmax,+Rmax
72 stt2=(2.0d0*xprobmax1)/(dble(vlim2)-1.d0)
73 ! z-coordinate between Zmin,Zmax
74 stt3=(xprobmax2-xprobmin2)/(dble(vlim3)-1.d0)
75 }
76 ^d&iip^d=floor((xcar(ix^dd,^d)-xcarmin^d)/stt^d)+1;
77 ^d&iip^d=max(1,iip^d);
78 case(spherical)
79 call mpistop("random_heating_3D to be adjusted for this geometry")
80 case default
81 call mpistop("random_heating_3D to be adjusted for this geometry")
82 end select
83 pulse1=(^d&va^d(iip^d+(i-4)*vlim^d)|*)
84 pulse2=(^d&va^d(iip^d+(i-3)*vlim^d)|*)
85 pulse3=(^d&va^d(iip^d+(i-2)*vlim^d)|*)
86 pulse4=(^d&va^d(iip^d+(i-1)*vlim^d)|*)
87 pulse5=(^d&va^d(iip^d+(i)*vlim^d)|*)
88 pulse6=(^d&va^d(iip^d+(i+1)*vlim^d)|*)
89 lqgrid(ix^d) = tl1 * pulse1 + tl2 *pulse2 &
90 +tl3 * pulse3 + tl4 *pulse4 &
91 +tl5 * pulse5 + tl6 *pulse6
92 {enddo\}
93 exit
94 endif
95 enddo
96
97 lqgrid(ixo^s)=tr*lqgrid(ixo^s)
98
99 end subroutine getlqgrid
100
101 subroutine generatetv(ntimes,vlim^D,periods,variation,nwaves,si)
102 integer, intent(in) :: ntimes,vlim^D,nwaves
103 double precision, intent(in) :: periods,variation,si
104 integer :: i,vx^D,j
105
106 ! generate random T, typically 300s +/- 75s
107
108 allocate(dtimearr(ntimes))
109 allocate(timearray(ntimes))
110
111 if (mype==0) then
112 call randomt(timearray,ntimes,periods,variation)
114 do i = 2, ntimes
115 dtimearr(i) = timearray(i) - timearray(i-1)
116 enddo
117 endif
118 call mpi_barrier(icomm,ierrmpi)
119 if (npe>1) then
120 call mpi_bcast(timearray,ntimes,mpi_double_precision,0,icomm,ierrmpi)
121 call mpi_bcast(dtimearr,ntimes,mpi_double_precision,0,icomm,ierrmpi)
122 endif
123
124 ! spatial distribution
125
126 {^d&
127 vx^d=ntimes*vlim^d
128 allocate(va^d(vx^d))
129 if (mype==0) then
130 call randomv(^d,va^d,ntimes,vlim^d,nwaves,si)
131 endif
132 call mpi_barrier(icomm,ierrmpi)
133 if (npe>1) then
134 call mpi_bcast(va^d,vx^d,mpi_double_precision,0,icomm,ierrmpi)
135 endif
136 }
137
138 end subroutine generatetv
139
140 subroutine randomt(tb,ntimes,periods,variation)
141 integer, intent(in) :: ntimes
142 double precision, intent(in) :: periods,variation
143 double precision, intent(inout) :: tb(:)
144
145 character(len=100) :: filename
146 double precision :: tt1,tt,mm
147 integer :: i
148
149 tt = 0.d0
150 do i = 1, ntimes
151 call random_number(mm)
152 tt1 = periods + variation * 2. * (mm - 0.5)
153 tt = tt + tt1
154 tb(i) = tt / unit_time
155 end do
156
157 write(filename,"(a)") "randomtimes.dat"
158 open(unit=21,file=filename,form='formatted',status='replace')
159 write(21,'(es12.4)') tb
160 close(21)
161
162 end subroutine randomt
163
164 subroutine randomv(ival,va,ntimes,vlim,nwaves,si)
165 integer, intent(in) :: ival,ntimes,vlim,nwaves
166 double precision, intent(in) :: si
167 double precision, intent(inout) :: va(:)
168
169 character(len=100) :: filename
170 character(len=10) :: xdirection
171
172 double precision, allocatable :: vn(:,:),vm(:)
173 double precision :: lambda,ampl,lambda_min,lambda_max,rms,phase
174 integer :: i, j, kk
175
176 allocate(vn(nwaves, vlim))
177 allocate(vm(vlim))
178 lambda_min = 1.d0/dble(vlim)
179 lambda_max = 1.d0
180 do kk = 1, ntimes
181 do i = 1, nwaves
182 lambda = (dble(i-1)/dble(nwaves-1))*(lambda_max-lambda_min)+lambda_min
183 ampl = lambda**si
184 call random_number(phase)
185 ! phase to vary between -2pi-->+2pi
186 phase=4.0d0*dpi*(phase-0.5d0)
187 do j = 1, vlim
188 vn(i,j) = ampl*dsin(2.d0*dpi*(dble(j-1)/dble(vlim-1))/lambda+phase)
189 end do
190 end do
191 rms = 0.d0
192 vm = 0.d0
193 do j = 1, vlim
194 ! sum all the waves in grid point j
195 do i = 1, nwaves
196 vm(j) = vm(j) + vn(i, j)
197 end do
198 rms = rms + vm(j)**2
199 end do
200 vm = vm / dsqrt(rms/vlim) ! normalization
201 do j = 1, vlim
202 va(vlim*(kk-1)+j) = vm(j)**2
203 end do
204 end do
205
206 write(xdirection,'(I2.2)') ival
207 write(filename,"(a)") "randompositions"//trim(xdirection)//".dat"
208 open(unit=22,file=filename,form='formatted',status='replace')
209 write(22,'(es12.4)') va
210 close(22)
211
212 deallocate(vm)
213 deallocate(vn)
214
215 end subroutine randomv
216
217end module mod_random_heating_3d
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module with geometry-related routines (e.g., divergence, curl)
Definition mod_geometry.t:2
integer coordinate
Definition mod_geometry.t:7
integer, parameter spherical
integer, parameter cartesian
Definition mod_geometry.t:8
integer, parameter cylindrical
This module contains definitions of global parameters and variables and some generic functions/subrou...
double precision, dimension(:), allocatable, parameter d
integer r_
Indices for cylindrical coordinates FOR TESTS, negative value when not used:
double precision, dimension(:), allocatable timearray
subroutine getlqgrid(lqgrid, ixil, ixol, qt, trelax, tramp, x, ntimes, vlimd)
subroutine randomv(ival, va, ntimes, vlim, nwaves, si)
double precision, allocatable va
subroutine generatetv(ntimes, vlimd, periods, variation, nwaves, si)
subroutine randomt(tb, ntimes, periods, variation)
double precision, dimension(:), allocatable dtimearr