MPI-AMRVAC 3.2
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 !> Only implemented for hll flavour of CT
178 subroutine reconstruct(ixI^L,ixC^L,idir,q,qL,qR)
179 use mod_limiter
181
182 integer, intent(in) :: ixI^L, ixC^L, idir
183 double precision, intent(in) :: q(ixI^S)
184 double precision, intent(out) :: qL(ixI^S), qR(ixI^S)
185
186 double precision :: qC(ixI^S)
187 double precision,dimension(ixI^S) :: dqC,ldq,rdq
188 integer :: ixO^L,jxC^L,gxC^L,hxC^L
189
190 jxc^l=ixc^l+kr(idir,^d);
191 gxcmin^d=ixcmin^d-kr(idir,^d);gxcmax^d=jxcmax^d;
192 hxc^l=gxc^l+kr(idir,^d);
193
194 qr(gxc^s) = q(hxc^s)
195 ql(gxc^s) = q(gxc^s)
196
197 select case (type_limiter(block%level))
198 case (limiter_ppm)
199 ! the ordinary grid-index:
200 ixomin^d=ixcmin^d+kr(idir,^d);
201 ixomax^d=ixcmax^d;
202 call ppmlimitervar(ixi^l,ixo^l,idir,q,q,ql,qr)
203 case (limiter_mp5)
204 call mp5limitervar(ixi^l,ixc^l,idir,q,ql,qr)
205 case (limiter_weno3)
206 call weno3limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,1)
207 case (limiter_wenoyc3)
208 call weno3limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,2)
209 case (limiter_weno5)
210 call weno5limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,1)
211 case (limiter_weno5nm)
212 call weno5nmlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,1)
213 case (limiter_wenoz5)
214 call weno5limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,2)
215 case (limiter_wenoz5nm)
216 call weno5nmlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,2)
217 case (limiter_wenozp5)
218 call weno5limiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,3)
219 case (limiter_wenozp5nm)
220 call weno5nmlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr,3)
221 case (limiter_weno5cu6)
222 call weno5cu6limiter(ixi^l,ixc^l,idir,q,ql,qr)
223 case (limiter_teno5ad)
224 call teno5adlimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr)
225 case (limiter_weno7)
226 call weno7limiter(ixi^l,ixc^l,idir,q,ql,qr,1)
227 case (limiter_mpweno7)
228 call weno7limiter(ixi^l,ixc^l,idir,q,ql,qr,2)
229 case (limiter_venk)
230 call venklimiter(ixi^l,ixc^l,idir,dxlevel(idir),q,ql,qr)
231 case default
232 dqc(gxc^s)= qr(gxc^s)-ql(gxc^s)
233 call dwlimiter2(dqc,ixi^l,gxc^l,idir,type_limiter(block%level),ldq,rdq)
234 ql(ixc^s) = ql(ixc^s) + half*ldq(ixc^s)
235 qr(ixc^s) = qr(ixc^s) - half*rdq(jxc^s)
236 end select
237
238 end subroutine reconstruct
239
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:35
integer, parameter limiter_mpweno7
Definition mod_limiter.t:38
integer, parameter limiter_teno5ad
Definition mod_limiter.t:36
integer, parameter limiter_weno3
Definition mod_limiter.t:27
integer, parameter limiter_ppm
Definition mod_limiter.t:25
subroutine dwlimiter2(dwc, ixil, ixcl, idims, typelim, ldw, rdw)
Limit the centered dwC differences within ixC for iw in direction idim. The limiter is chosen accordi...
integer, parameter limiter_wenozp5
Definition mod_limiter.t:33
integer, parameter limiter_weno5
Definition mod_limiter.t:29
integer, parameter limiter_wenoz5
Definition mod_limiter.t:31
integer, parameter limiter_wenoz5nm
Definition mod_limiter.t:32
integer, parameter limiter_weno7
Definition mod_limiter.t:37
integer, parameter limiter_wenozp5nm
Definition mod_limiter.t:34
integer, parameter limiter_mp5
Definition mod_limiter.t:26
integer, parameter limiter_venk
Definition mod_limiter.t:23
integer, parameter limiter_weno5nm
Definition mod_limiter.t:30
integer, parameter limiter_wenoyc3
Definition mod_limiter.t:28
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:52
procedure(sub_convert), pointer phys_to_conserved
Definition mod_physics.t:51
procedure(sub_face_to_center), pointer phys_face_to_center
Definition mod_physics.t:87
Module with all the methods that users can customize in AMRVAC.
procedure(init_vector_potential), pointer usr_init_vector_potential