MPI-AMRVAC 3.1
The MPI - Adaptive Mesh Refinement - Versatile Advection Code (development version)
Loading...
Searching...
No Matches
mod_constrained_transport.t
Go to the documentation of this file.
2 implicit none
3 public
4
5contains
6 !> re-calculate the magnetic field from the vector potential in a completely
7 !> divergency free way
8 subroutine recalculateb
11 use mod_physics
13
14 integer :: igrid,iigrid
15
17
18 !$OMP PARALLEL DO PRIVATE(igrid)
19 do iigrid=1,igridstail; igrid=igrids(iigrid);
20 ! Make zero the magnetic fluxes
21 ! Fake advance, storing electric fields at edges
22 block=>ps(igrid)
23 call fake_advance(igrid,1,^nd,ps(igrid))
24
25 end do
26 !$OMP END PARALLEL DO
27
28 ! Do correction
29 call recvflux(1,ndim)
30 call sendflux(1,ndim)
31 call fix_conserve(ps,1,ndim,1,^nd)
32
33 call fix_edges(ps,1,^nd)
34
35 ! Now we fill the centers for the staggered variables
36 !$OMP PARALLEL DO PRIVATE(igrid)
37 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
38 call phys_to_primitive(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x)
39 ! update cell center magnetic field
40 call phys_face_to_center(ixm^ll,ps(igrid))
41 call phys_to_conserved(ixg^ll,ixm^ll,ps(igrid)%w,ps(igrid)%x)
42 end do
43 !$OMP END PARALLEL DO
44
45 call getbc(global_time,0.d0,ps,iwstart,nwgc)
46
47 end subroutine recalculateb
48
49 !> fake advance a step to calculate magnetic field
50 subroutine fake_advance(igrid,idim^LIM,s)
53
54 integer :: igrid,idim^LIM
55 type(state) :: s
56
57 double precision :: dx^D
58 double precision :: fC(ixG^T,1:nwflux,1:ndim)
59 double precision :: fE(ixG^T,sdim:3)
60
61 dx^d=rnode(rpdx^d_,igrid);
62
63 call fake_update(ixg^ll,s,fc,fe,dx^d)
64
65 call store_flux(igrid,fc,idim^lim,^nd)
66 call store_edge(igrid,ixg^ll,fe,idim^lim)
67
68 end subroutine fake_advance
69
70 !>fake update magnetic field from vector potential
71 subroutine fake_update(ixI^L,s,fC,fE,dx^D)
73
74 integer :: ixI^L
75 type(state) :: s
76 double precision :: fC(ixI^S,1:nwflux,1:ndim)
77 double precision :: fE(ixI^S,sdim:3)
78 double precision :: dx^D
79
80 double precision :: A(s%ixGs^S,1:3)
81 integer :: ixIs^L,ixO^L,idir
82
83 associate(ws=>s%ws,x=>s%x)
84
85 a=zero
86 ws=zero
87
88 ixis^l=s%ixGs^l;
89 ixo^l=ixi^l^lsubnghostcells;
90
91 fc=0.d0
92 call b_from_vector_potentiala(ixis^l, ixi^l, ixo^l, ws, x, a)
93
94 ! This is important only in 3D
95 do idir=sdim,3
96 fe(ixi^s,idir) =-a(ixi^s,idir)
97 end do
98
99 end associate
100 end subroutine fake_update
101
102 !> calculate magnetic field from vector potential A at cell edges
103 subroutine b_from_vector_potentiala(ixIs^L, ixI^L, ixO^L, ws, x, A)
106
107 integer, intent(in) :: ixIs^L, ixI^L, ixO^L
108 double precision, intent(inout) :: ws(ixIs^S,1:nws),A(ixIs^S,1:3)
109 double precision, intent(in) :: x(ixI^S,1:ndim)
110
111 double precision :: xC(ixIs^S,1:ndim),xCC(ixIs^S,1:ndim)
112 double precision :: circ(ixIs^S,1:ndim)
113 integer :: ixC^L, hxC^L, idim1, idim2, idir
114
115 a=zero
116 ! extend one layer of cell center locations in xCC
117 xc=0.d0
118 xcc=0.d0
119 xcc(ixi^s,1:ndim)=x(ixi^s,1:ndim)
120 {
121 xcc(ixismin^d^d%ixI^s,1:ndim)=x(iximin^d^d%ixI^s,1:ndim)
122 xcc(ixismin^d^d%ixIs^s,^d)=x({iximin^dd,},^d)-block%dx({iximin^dd,},^d)
123 \}
124 {^ifthreed
125 xcc(iximin1:iximax1,ixismin2,ixismin3,1)=x(iximin1:iximax1,iximin2,iximin3,1)
126 xcc(ixismin1,iximin2:iximax2,ixismin3,2)=x(iximin1,iximin2:iximax2,iximin3,2)
127 xcc(ixismin1,ixismin2,iximin3:iximax3,3)=x(iximin1,iximin2,iximin3:iximax3,3)
128 }
129
130 do idir=sdim,3
131 ixcmax^d=ixomax^d;
132 ixcmin^d=ixomin^d-1+kr(idir,^d);
133 do idim1=1,ndim
134 ! Get edge coordinates
135 if (idim1/=idir) then
136 xc(ixc^s,idim1)=xcc(ixc^s,idim1)+half*block%dx(ixc^s,idim1)
137 else
138 xc(ixc^s,idim1)=xcc(ixc^s,idim1)
139 end if
140 end do
141 ! Initialise vector potential at the edge
142 call usr_init_vector_potential(ixis^l, ixc^l, xc, a(ixis^s,idir), idir)
143 a(ixc^s,idir)=a(ixc^s,idir)*block%dsC(ixc^s,idir)
144 end do
145
146 ! Take the curl of the vector potential
147 circ=zero
148 ! Calculate circulation on each face
149 do idim1=1,ndim ! Coordinate perpendicular to face
150 ixcmax^d=ixomax^d;
151 ixcmin^d=ixomin^d-kr(idim1,^d);
152 do idim2=1,ndim
153 do idir=sdim,3 ! Direction of line integral
154 if(lvc(idim1,idim2,idir)==0) cycle
155 ! Assemble indices
156 hxc^l=ixc^l-kr(idim2,^d);
157 ! Add line integrals in direction idir
158 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
159 +lvc(idim1,idim2,idir)* &
160 (a(ixc^s,idir)&
161 -a(hxc^s,idir))
162 end do
163 end do
164 ! Divide by the area of the face to get B
165 where(block%surfaceC(ixc^s,idim1)==0)
166 circ(ixc^s,idim1)=zero
167 elsewhere
168 circ(ixc^s,idim1)=circ(ixc^s,idim1)/block%surfaceC(ixc^s,idim1)
169 end where
170 ws(ixc^s,idim1) = circ(ixc^s,idim1)
171 end do
172
173 end subroutine b_from_vector_potentiala
174
175 !> Reconstruct scalar q within ixO^L to 1/2 dx in direction idir
176 !> Return both left and right reconstructed values
177 subroutine reconstruct(ixI^L,ixC^L,idir,q,qL,qR)
178 use mod_limiter
180
181 integer, intent(in) :: ixI^L, ixC^L, idir
182 double precision, intent(in) :: q(ixI^S)
183 double precision, intent(out) :: qL(ixI^S), qR(ixI^S)
184
185 double precision :: qC(ixI^S)
186 double precision,dimension(ixI^S) :: dqC,ldq,rdq
187 integer :: ixO^L,jxC^L,gxC^L,hxC^L
188
189 jxc^l=ixc^l+kr(idir,^d);
190 gxcmin^d=ixcmin^d-kr(idir,^d);gxcmax^d=jxcmax^d;
191 hxc^l=gxc^l+kr(idir,^d);
192
193 qr(gxc^s) = q(hxc^s)
194 ql(gxc^s) = q(gxc^s)
195
196 select case (type_limiter(block%level))
197 case (limiter_ppm)
198 ! the ordinary grid-index:
199 ixomin^d=ixcmin^d+kr(idir,^d);
200 ixomax^d=ixcmax^d;
201 call ppmlimitervar(ixi^l,ixo^l,idir,q,q,ql,qr)
202 case (limiter_mp5)
203 call mp5limitervar(ixi^l,ixc^l,idir,q,ql,qr)
204 case (limiter_weno3)
205 call weno3limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,1)
206 case (limiter_wenoyc3)
207 call weno3limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,2)
208 case (limiter_weno5)
209 call weno5limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,1)
210 case (limiter_weno5nm)
211 call weno5nmlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,1)
212 case (limiter_wenoz5)
213 call weno5limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,2)
214 case (limiter_wenoz5nm)
215 call weno5nmlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,2)
216 case (limiter_wenozp5)
217 call weno5limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,3)
218 case (limiter_wenozp5nm)
219 call weno5nmlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,3)
220 case (limiter_weno5cu6)
221 call weno5cu6limiter(ixi^l,ixc^l,idir,q,ql,qr)
222 case (limiter_teno5ad)
223 call teno5adlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr)
224 case (limiter_weno7)
225 call weno7limiter(ixi^l,ixc^l,idir,q,ql,qr,1)
226 case (limiter_mpweno7)
227 call weno7limiter(ixi^l,ixc^l,idir,q,ql,qr,2)
228 case (limiter_venk)
229 call venklimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr)
230 case default
231 dqc(gxc^s)= qr(gxc^s)-ql(gxc^s)
232 call dwlimiter2(dqc,ixi^l,gxc^l,idir,type_limiter(block%level),ldq,rdq)
233 ql(ixc^s) = ql(ixc^s) + half*ldq(ixc^s)
234 qr(ixc^s) = qr(ixc^s) - half*rdq(jxc^s)
235 end select
236
237 end subroutine reconstruct
238
subroutine recalculateb
re-calculate the magnetic field from the vector potential in a completely divergency free way
subroutine fake_advance(igrid, idimlim, s)
fake advance a step to calculate magnetic field
subroutine reconstruct(ixil, ixcl, idir, q, ql, qr)
Reconstruct scalar q within ixO^L to 1/2 dx in direction idir Return both left and right reconstructe...
subroutine b_from_vector_potentiala(ixisl, ixil, ixol, ws, x, a)
calculate magnetic field from vector potential A at cell edges
subroutine fake_update(ixil, s, fc, fe, dxd)
fake update magnetic field from vector potential
Module for flux conservation near refinement boundaries.
subroutine, public init_comm_fix_conserve(idimlim, nwfluxin)
subroutine, public fix_edges(psuse, idimlim)
subroutine, public recvflux(idimlim)
subroutine, public sendflux(idimlim)
subroutine, public store_flux(igrid, fc, idimlim, nwfluxin)
subroutine, public store_edge(igrid, ixil, fe, idimlim)
subroutine, public fix_conserve(psb, idimlim, nw0, nwfluxin)
update ghost cells of all blocks including physical boundaries
subroutine getbc(time, qdt, psb, nwstart, nwbc)
do update ghost cells of all blocks including physical boundaries
This module contains definitions of global parameters and variables and some generic functions/subrou...
type(state), pointer block
Block pointer for using one block and its previous state.
integer, dimension(3, 3, 3) lvc
Levi-Civita tensor.
double precision global_time
The global simulation time.
integer, dimension(3, 3) kr
Kronecker delta tensor.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision, dimension(:), allocatable, parameter d
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
integer, dimension(:), allocatable type_limiter
Type of slope limiter used for reconstructing variables on cell edges.
integer, parameter sdim
starting dimension for electric field
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
Module with slope/flux limiters.
Definition mod_limiter.t:2
integer, parameter limiter_weno5cu6
Definition mod_limiter.t:37
integer, parameter limiter_mpweno7
Definition mod_limiter.t:40
integer, parameter limiter_teno5ad
Definition mod_limiter.t:38
integer, parameter limiter_weno3
Definition mod_limiter.t:29
integer, parameter limiter_ppm
Definition mod_limiter.t:27
double precision d
Definition mod_limiter.t:14
integer, parameter limiter_wenozp5
Definition mod_limiter.t:35
integer, parameter limiter_weno5
Definition mod_limiter.t:31
integer, parameter limiter_wenoz5
Definition mod_limiter.t:33
integer, parameter limiter_wenoz5nm
Definition mod_limiter.t:34
integer, parameter limiter_weno7
Definition mod_limiter.t:39
integer, parameter limiter_wenozp5nm
Definition mod_limiter.t:36
subroutine dwlimiter2(dwc, ixil, ixcl, idims, typelim, ldw, rdw, a2max)
Limit the centered dwC differences within ixC for iw in direction idim. The limiter is chosen accordi...
integer, parameter limiter_mp5
Definition mod_limiter.t:28
integer, parameter limiter_venk
Definition mod_limiter.t:25
integer, parameter limiter_weno5nm
Definition mod_limiter.t:32
integer, parameter limiter_wenoyc3
Definition mod_limiter.t:30
This module defines the procedures of a physics module. It contains function pointers for the various...
Definition mod_physics.t:4
procedure(sub_convert), pointer phys_to_primitive
Definition mod_physics.t:55
procedure(sub_convert), pointer phys_to_conserved
Definition mod_physics.t:54
procedure(sub_face_to_center), pointer phys_face_to_center
Definition mod_physics.t:81
Module with all the methods that users can customize in AMRVAC.
procedure(init_vector_potential), pointer usr_init_vector_potential