12 double precision,
public ::
mf_nu = 1.d-15
15 double precision,
public ::
mf_vmax = 3.d6
24 logical,
public,
protected ::
mf_glm = .false.
40 integer,
allocatable,
public,
protected ::
mom(:)
44 integer,
public,
protected ::
psi_
47 double precision,
public ::
mf_eta = 0.0d0
53 character(len=std_len),
public,
protected ::
typedivbfix =
'ct'
56 character(len=std_len),
public,
protected ::
type_ct =
'average'
65 double precision :: divbdiff = 0.8d0
68 character(len=std_len) :: typedivbdiff =
'all'
71 logical :: compactres = .false.
89 integer,
parameter :: divb_none = 0
90 integer,
parameter :: divb_multigrid = -1
91 integer,
parameter :: divb_glm = 1
92 integer,
parameter :: divb_powel = 2
93 integer,
parameter :: divb_janhunen = 3
94 integer,
parameter :: divb_linde = 4
95 integer,
parameter :: divb_lindejanhunen = 5
96 integer,
parameter :: divb_lindepowel = 6
97 integer,
parameter :: divb_lindeglm = 7
98 integer,
parameter :: divb_ct = 8
121 subroutine mf_read_params(files)
124 character(len=*),
intent(in) :: files(:)
135 do n = 1,
size(files)
136 open(
unitpar, file=trim(files(n)), status=
"old")
137 read(
unitpar, mf_list,
end=111)
141 end subroutine mf_read_params
146 integer,
intent(in) :: fh
147 integer,
parameter :: n_par = 1
148 double precision :: values(n_par)
149 character(len=name_len) :: names(n_par)
150 integer,
dimension(MPI_STATUS_SIZE) :: st
153 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
157 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
158 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
180 type_divb = divb_none
183 type_divb = divb_multigrid
185 mg%operator_type = mg_laplacian
192 case (
'powel',
'powell')
193 type_divb = divb_powel
195 type_divb = divb_janhunen
197 type_divb = divb_linde
198 case (
'lindejanhunen')
199 type_divb = divb_lindejanhunen
201 type_divb = divb_lindepowel
205 type_divb = divb_lindeglm
210 call mpistop(
'Unknown divB fix')
218 mom(:) = var_set_momentum(
ndir)
222 mag(:) = var_set_bfield(
ndir)
226 allocate(start_indices(number_species),stop_indices(number_species))
228 start_indices(1)=mag(1)
231 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
240 stop_indices(1)=nwflux
246 allocate(iw_vector(nvector))
247 iw_vector(1) =
mom(1) - 1
248 iw_vector(2) = mag(1) - 1
255 call mpistop(
"phys_check error: flux_type has wrong shape")
275 if(type_divb==divb_glm)
then
290 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
320 double precision :: mp,kB,miu0,c_lightspeed
380 integer,
intent(in) :: ixi^
l, ixo^
l
381 double precision,
intent(inout) :: w(ixi^s, nw)
382 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
390 integer,
intent(in) :: ixi^
l, ixo^
l
391 double precision,
intent(inout) :: w(ixi^s, nw)
392 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
401 integer,
intent(in) :: ixi^
l, ixo^
l
402 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
403 double precision,
intent(out) :: v(ixi^s,
ndir)
408 v(ixo^s,idir) = w(ixo^s,
mom(idir))
417 integer,
intent(in) :: ixi^
l, ixo^
l, idim
418 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
419 double precision,
intent(out) :: v(ixi^s)
421 v(ixo^s) = w(ixo^s,
mom(idim))
429 integer,
intent(in) :: ixI^L, ixO^L, idim
430 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
431 double precision,
intent(inout) :: cmax(ixI^S)
433 cmax(ixo^s)=abs(w(ixo^s,
mom(idim)))+one
438 subroutine mf_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
442 integer,
intent(in) :: ixI^L, ixO^L, idim
443 double precision,
intent(in) :: wLC(ixI^S, nw), wRC(ixI^S, nw)
444 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
445 double precision,
intent(in) :: x(ixI^S,1:ndim)
446 double precision,
intent(inout) :: cmax(ixI^S,1:number_species)
447 double precision,
intent(inout),
optional :: cmin(ixI^S,1:number_species)
448 double precision,
intent(in) :: Hspeed(ixI^S,1:number_species)
450 double precision,
dimension(ixI^S) :: tmp1
452 tmp1(ixo^s)=0.5d0*(wlc(ixo^s,
mom(idim))+wrc(ixo^s,
mom(idim)))
453 if(
present(cmin))
then
454 cmax(ixo^s,1)=max(tmp1(ixo^s)+one,zero)
455 cmin(ixo^s,1)=min(tmp1(ixo^s)-one,zero)
457 cmax(ixo^s,1)=abs(tmp1(ixo^s))+one
466 integer,
intent(in) :: ixI^L, ixO^L, idim
467 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
468 double precision,
intent(in) :: cmax(ixI^S)
469 double precision,
intent(in),
optional :: cmin(ixI^S)
470 type(ct_velocity),
intent(inout):: vcts
472 integer :: idimE,idimN
478 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
480 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
482 if(.not.
allocated(vcts%vbarC))
then
483 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
484 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
487 if(
present(cmin))
then
488 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
489 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
491 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
492 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
495 idimn=mod(idim,
ndir)+1
496 idime=mod(idim+1,
ndir)+1
498 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
499 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
500 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
501 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
502 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
504 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
505 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
506 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
507 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
508 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
510 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
519 integer,
intent(in) :: ixI^L, ixO^L
520 double precision,
intent(in) :: w(ixI^S,nw)
521 double precision,
intent(in) :: x(ixI^S,1:ndim)
522 double precision,
intent(out) :: p(ixI^S)
524 p(ixo^s) = 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=ndim+1)
534 integer,
intent(in) :: ixI^L, ixO^L, idim
536 double precision,
intent(in) :: wC(ixI^S,nw)
538 double precision,
intent(in) :: w(ixI^S,nw)
539 double precision,
intent(in) :: x(ixI^S,1:ndim)
540 double precision,
intent(out) :: f(ixI^S,nwflux)
553 f(ixo^s,mag(idir))=w(ixo^s,
psi_)
555 f(ixo^s,mag(idir))=zero
558 f(ixo^s,mag(idir))=w(ixo^s,
mom(idim))*w(ixo^s,mag(idir))-w(ixo^s,mag(idim))*w(ixo^s,
mom(idir))
573 double precision,
intent(in) :: qt
574 type(state),
target :: psa(max_blocks)
576 integer :: iigrid,igrid
577 logical :: stagger_flag
578 logical :: firstmf=.true.
593 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
622 subroutine mf_add_source(qdt,dtfactor,ixI^L,ixO^L,wCT,wCTprim,w,x,qsourcesplit,active)
625 integer,
intent(in) :: ixI^L, ixO^L
626 double precision,
intent(in) :: qdt, dtfactor
627 double precision,
intent(in) :: wCT(ixI^S,1:nw),wCTprim(ixI^S,1:nw), x(ixI^S,1:ndim)
628 double precision,
intent(inout) :: w(ixI^S,1:nw)
629 logical,
intent(in) :: qsourcesplit
630 logical,
intent(inout) :: active
632 if (.not. qsourcesplit)
then
635 if (abs(
mf_eta)>smalldouble)
then
650 select case (type_divb)
665 case (divb_lindejanhunen)
669 case (divb_lindepowel)
679 case (divb_multigrid)
682 call mpistop(
'Unknown divB fix')
692 integer,
intent(in) :: ixI^L, ixO^L
693 double precision,
intent(in) :: x(ixI^S,1:ndim)
694 double precision,
intent(inout) :: w(ixI^S,1:nw)
696 double precision :: xmin(ndim),xmax(ndim)
697 double precision :: decay(ixO^S)
698 double precision :: current(ixI^S,7-2*ndir:3),tmp(ixO^S)
699 integer :: ix^D, idirmin,idir,jdir,kdir
705 if(
block%is_physical_boundary(2*^d-1))
then
708 if(2*^d-1==5.and.ndim==3)
then
710 current(ixomin^d^d%ixO^s,:)=current(ixomin^d+1^d%ixO^s,:)
715 current(ixomin^d^d%ixO^s,:)=current(ixomin^d+1^d%ixO^s,:)
719 if(
block%is_physical_boundary(2*^d))
then
720 current(ixomax^d^d%ixO^s,:)=current(ixomax^d-1^d%ixO^s,:)
725 do idir=1,ndir;
do jdir=idirmin,3;
do kdir=1,ndir
726 if(
lvc(idir,jdir,kdir)/=0)
then
727 if(
lvc(idir,jdir,kdir)==1)
then
728 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))+current(ixo^s,jdir)*w(ixo^s,mag(kdir))
730 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-current(ixo^s,jdir)*w(ixo^s,mag(kdir))
733 end do;
end do;
end do
735 tmp(ixo^s)=sum(w(ixo^s,mag(:))**2,dim=ndim+1)
737 where(tmp(ixo^s)/=0.d0)
738 tmp(ixo^s)=1.d0/(tmp(ixo^s)*
mf_nu)
742 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))*tmp(ixo^s)
746 ^d&xmin(^d)=xprobmin^d\
747 ^d&xmax(^d)=xprobmax^d\
757 tmp(ixo^s)=sqrt(sum(w(ixo^s,
mom(:))**2,dim=ndim+1))/
mf_vmax+1.d-12
758 tmp(ixo^s)=dtanh(tmp(ixo^s))/tmp(ixo^s)
760 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))*tmp(ixo^s)*decay(ixo^s)
774 integer,
intent(in) :: ixI^L, ixO^L
775 double precision,
intent(in) :: qdt
776 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
777 double precision,
intent(inout) :: w(ixI^S,1:nw)
778 integer :: ixA^L,idir,jdir,kdir,idirmin,idim,jxO^L,hxO^L,ix
779 integer :: lxO^L, kxO^L
781 double precision :: tmp(ixI^S),tmp2(ixI^S)
784 double precision :: current(ixI^S,7-2*ndir:3),eta(ixI^S)
785 double precision :: gradeta(ixI^S,1:ndim), Bf(ixI^S,1:ndir)
794 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
795 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
802 gradeta(ixo^s,1:ndim)=zero
807 call gradient(eta,ixi^l,ixo^l,idim,tmp)
808 gradeta(ixo^s,idim)=tmp(ixo^s)
812 bf(ixi^s,1:ndir)=wct(ixi^s,mag(1:ndir))
818 tmp2(ixi^s)=bf(ixi^s,idir)
820 lxo^l=ixo^l+2*
kr(idim,^
d);
821 jxo^l=ixo^l+
kr(idim,^
d);
822 hxo^l=ixo^l-
kr(idim,^
d);
823 kxo^l=ixo^l-2*
kr(idim,^
d);
824 tmp(ixo^s)=tmp(ixo^s)+&
825 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
830 tmp2(ixi^s)=bf(ixi^s,idir)
832 jxo^l=ixo^l+
kr(idim,^
d);
833 hxo^l=ixo^l-
kr(idim,^
d);
834 tmp(ixo^s)=tmp(ixo^s)+&
835 (tmp2(jxo^s)-2.0d0*tmp2(ixo^s)+tmp2(hxo^s))/
dxlevel(idim)**2
840 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
844 do jdir=1,ndim;
do kdir=idirmin,3
845 if (
lvc(idir,jdir,kdir)/=0)
then
846 if (
lvc(idir,jdir,kdir)==1)
then
847 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
849 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
856 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))+qdt*tmp(ixo^s)
869 integer,
intent(in) :: ixI^L, ixO^L
870 double precision,
intent(in) :: qdt
871 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
872 double precision,
intent(inout) :: w(ixI^S,1:nw)
875 double precision :: current(ixI^S,7-2*ndir:3),eta(ixI^S),curlj(ixI^S,1:3)
876 double precision :: tmpvec(ixI^S,1:3)
877 integer :: ixA^L,idir,idirmin,idirmin1
884 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
885 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
899 tmpvec(ixa^s,1:ndir)=zero
901 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
904 call curlvector(tmpvec,ixi^l,ixo^l,curlj,idirmin1,1,3)
906 if(ndim==2.and.ndir==3)
then
908 w(ixo^s,mag(ndir)) = w(ixo^s,mag(ndir))-qdt*curlj(ixo^s,ndir)
911 w(ixo^s,mag(1:ndir)) = w(ixo^s,mag(1:ndir))-qdt*curlj(ixo^s,1:ndir)
922 integer,
intent(in) :: ixI^L, ixO^L
923 double precision,
intent(in) :: qdt
924 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
925 double precision,
intent(inout) :: w(ixI^S,1:nw)
927 double precision :: current(ixI^S,7-2*ndir:3)
928 double precision :: tmpvec(ixI^S,1:3),tmpvec2(ixI^S,1:3),tmp(ixI^S),ehyper(ixI^S,1:3)
929 integer :: ixA^L,idir,jdir,kdir,idirmin,idirmin1
932 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
933 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
936 tmpvec(ixa^s,1:ndir)=zero
938 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
942 call curlvector(tmpvec,ixi^l,ixa^l,tmpvec2,idirmin1,1,3)
945 tmpvec(ixa^s,1:ndir)=zero
946 call curlvector(tmpvec2,ixi^l,ixa^l,tmpvec,idirmin1,1,3)
947 ehyper(ixa^s,1:ndir) = - tmpvec(ixa^s,1:ndir)*
mf_eta_hyper
950 tmpvec2(ixa^s,1:ndir)=zero
951 call curlvector(ehyper,ixi^l,ixa^l,tmpvec2,idirmin1,1,3)
954 w(ixo^s,mag(idir)) = w(ixo^s,mag(idir))-tmpvec2(ixo^s,idir)*qdt
966 integer,
intent(in) :: ixI^L, ixO^L
967 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
968 double precision,
intent(inout) :: w(ixI^S,1:nw)
969 double precision:: divb(ixI^S)
971 double precision :: gradPsi(ixI^S)
1005 integer,
intent(in) :: ixI^L, ixO^L
1006 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1007 double precision,
intent(inout) :: w(ixI^S,1:nw)
1008 double precision :: divb(ixI^S),v(ixI^S,1:ndir)
1019 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))-qdt*v(ixo^s,idir)*divb(ixo^s)
1029 integer,
intent(in) :: ixI^L, ixO^L
1030 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1031 double precision,
intent(inout) :: w(ixI^S,1:nw)
1032 double precision :: divb(ixI^S),v(ixI^S,1:ndir)
1043 w(ixo^s,mag(idir))=w(ixo^s,mag(idir))-qdt*v(ixo^s,idir)*divb(ixo^s)
1053 integer,
intent(in) :: ixI^L, ixO^L
1054 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1055 double precision,
intent(inout) :: w(ixI^S,1:nw)
1056 integer :: idim, idir, ixp^L, i^D, iside
1057 double precision :: divb(ixI^S),graddivb(ixI^S)
1058 logical,
dimension(-1:1^D&) :: leveljump
1066 if(i^d==0|.and.) cycle
1067 if(neighbor_type(i^d,
block%igrid)==2 .or. neighbor_type(i^d,
block%igrid)==4)
then
1068 leveljump(i^d)=.true.
1070 leveljump(i^d)=.false.
1079 i^dd=kr(^dd,^d)*(2*iside-3);
1080 if (leveljump(i^dd))
then
1082 ixpmin^d=ixomin^d-i^d
1084 ixpmax^d=ixomax^d-i^d
1095 select case(typegrad)
1097 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
1099 call gradients(divb,ixi^l,ixp^l,idim,graddivb)
1103 if (slab_uniform)
then
1104 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
1106 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
1107 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
1110 w(ixp^s,mag(idim))=w(ixp^s,mag(idim))+graddivb(ixp^s)
1121 integer,
intent(in) :: ixi^
l, ixo^
l
1122 double precision,
intent(in) :: w(ixi^s,1:nw)
1123 double precision :: divb(ixi^s), dsurface(ixi^s)
1125 double precision :: invb(ixo^s)
1126 integer :: ixa^
l,idims
1128 call get_divb(w,ixi^
l,ixo^
l,divb)
1130 where(invb(ixo^s)/=0.d0)
1131 invb(ixo^s)=1.d0/invb(ixo^s)
1134 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
1136 ixamin^
d=ixomin^
d-1;
1137 ixamax^
d=ixomax^
d-1;
1138 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
1140 ixa^
l=ixo^
l-
kr(idims,^
d);
1141 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
1143 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
1144 block%dvolume(ixo^s)/dsurface(ixo^s)
1155 integer,
intent(in) :: ixo^
l, ixi^
l
1156 double precision,
intent(in) :: w(ixi^s,1:nw)
1157 integer,
intent(out) :: idirmin
1158 logical,
intent(in),
optional :: fourthorder
1159 integer :: idir, idirmin0
1162 double precision :: current(ixi^s,7-2*
ndir:3)
1166 if(
present(fourthorder))
then
1179 integer,
intent(in) :: ixI^L, ixO^L
1180 double precision,
intent(inout) :: dtnew
1181 double precision,
intent(in) :: dx^D
1182 double precision,
intent(in) :: w(ixI^S,1:nw)
1183 double precision,
intent(in) :: x(ixI^S,1:ndim)
1185 integer :: idirmin,idim
1186 double precision :: dxarr(ndim)
1187 double precision :: current(ixI^S,7-2*ndir:3),eta(ixI^S)
1194 else if (
mf_eta<zero)
then
1201 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
1204 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
1223 integer,
intent(in) :: ixI^L, ixO^L
1224 double precision,
intent(in) :: qdt, dtfactor, x(ixI^S,1:ndim)
1225 double precision,
intent(inout) :: wCT(ixI^S,1:nw), wprim(ixI^S,1:nw), w(ixI^S,1:nw)
1227 double precision :: tmp,invr,cs2
1228 integer :: iw,idir,ix^D
1230 integer :: mr_,mphi_
1231 integer :: br_,bphi_
1234 br_=mag(1); bphi_=mag(1)-1+
phi_
1240 {
do ix^db=ixomin^db,ixomax^db\}
1241 w(ix^d,bphi_)=w(ix^d,bphi_)+qdt/x(ix^d,1)*&
1242 (wct(ix^d,bphi_)*wct(ix^d,mr_) &
1243 -wct(ix^d,br_)*wct(ix^d,mphi_))
1247 if(
mf_glm) w(ixo^s,br_)=w(ixo^s,br_)+qdt*wct(ixo^s,
psi_)/x(ixo^s,1)
1249 {
do ix^db=ixomin^db,ixomax^db\}
1253 w(ix^d,mag(1))=w(ix^d,mag(1))+invr*2.0d0*wct(ix^d,
psi_)
1258 if(.not.stagger_grid)
then
1259 tmp=wct(ix^d,
mom(1))*wct(ix^d,mag(2))-wct(ix^d,
mom(2))*wct(ix^d,mag(1))
1260 cs2=1.d0/tan(x(ix^d,2))
1262 tmp=tmp+cs2*wct(ix^d,
psi_)
1264 w(ix^d,mag(2))=w(ix^d,mag(2))+tmp*invr
1271 if(.not.stagger_grid)
then
1272 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
1273 (wct(ix^d,
mom(1))*wct(ix^d,mag(3)) &
1274 -wct(ix^d,
mom(3))*wct(ix^d,mag(1)))
1279 if(.not.stagger_grid)
then
1280 w(ix^d,mag(3))=w(ix^d,mag(3))+invr*&
1281 (wct(ix^d,
mom(1))*wct(ix^d,mag(3)) &
1282 -wct(ix^d,
mom(3))*wct(ix^d,mag(1)) &
1283 -(wct(ix^d,
mom(3))*wct(ix^d,mag(2)) &
1284 -wct(ix^d,
mom(2))*wct(ix^d,mag(3)))*cs2)
1296 integer,
intent(in) :: ixi^
l, ixo^
l
1297 double precision,
intent(in) :: w(ixi^s, nw)
1298 double precision :: mge(ixo^s)
1300 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
1306 integer,
intent(in) :: ixi^
l, ixo^
l, idir
1307 double precision,
intent(in) :: w(ixi^s, nw)
1308 double precision :: mgf(ixo^s)
1310 mgf = w(ixo^s, mag(idir))
1316 integer,
intent(in) :: ixi^l, ixo^l
1317 double precision,
intent(in) :: w(ixi^s, nw)
1318 double precision :: mge(ixo^s)
1320 mge = 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
1326 integer,
intent(in) :: ixI^L, ixO^L, idir
1327 double precision,
intent(in) :: qt
1328 double precision,
intent(inout) :: wLC(ixI^S,1:nw), wRC(ixI^S,1:nw)
1329 double precision,
intent(inout) :: wLp(ixI^S,1:nw), wRp(ixI^S,1:nw)
1331 double precision :: dB(ixI^S), dPsi(ixI^S)
1339 db(ixo^s) = wrp(ixo^s,mag(idir)) - wlp(ixo^s,mag(idir))
1340 dpsi(ixo^s) = wrp(ixo^s,
psi_) - wlp(ixo^s,
psi_)
1342 wlp(ixo^s,mag(idir)) = 0.5d0 * (wrp(ixo^s,mag(idir)) + wlp(ixo^s,mag(idir))) &
1344 wlp(ixo^s,
psi_) = 0.5d0 * (wrp(ixo^s,
psi_) + wlp(ixo^s,
psi_)) &
1347 wrp(ixo^s,mag(idir)) = wlp(ixo^s,mag(idir))
1354 integer,
intent(in) :: igrid
1355 type(state),
target :: psb(max_blocks)
1357 integer :: iB, idims, iside, ixO^L, i^D
1366 i^d=
kr(^d,idims)*(2*iside-3);
1367 if (neighbor_type(i^d,igrid)/=1) cycle
1368 ib=(idims-1)*2+iside
1396 integer,
intent(in) :: ixG^L,ixO^L,iB
1397 double precision,
intent(inout) :: w(ixG^S,1:nw)
1398 double precision,
intent(in) :: x(ixG^S,1:ndim)
1400 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
1401 integer :: ix^D,ixF^L
1413 do ix1=ixfmax1,ixfmin1,-1
1414 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
1415 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
1416 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
1419 do ix1=ixfmax1,ixfmin1,-1
1420 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
1421 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
1422 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
1423 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
1424 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
1425 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
1426 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
1440 do ix1=ixfmax1,ixfmin1,-1
1441 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1442 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
1443 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
1444 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
1445 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
1446 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
1449 do ix1=ixfmax1,ixfmin1,-1
1450 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1451 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
1452 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
1453 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
1454 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
1455 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
1456 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
1457 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
1458 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
1459 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
1460 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
1461 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
1462 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
1463 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
1464 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1465 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
1466 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
1467 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
1479 do ix1=ixfmin1,ixfmax1
1480 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
1481 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
1482 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
1485 do ix1=ixfmin1,ixfmax1
1486 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
1487 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
1488 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
1489 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
1490 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
1491 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
1492 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
1506 do ix1=ixfmin1,ixfmax1
1507 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1508 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
1509 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
1510 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
1511 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
1512 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
1515 do ix1=ixfmin1,ixfmax1
1516 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1517 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
1518 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
1519 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
1520 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
1521 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
1522 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
1523 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
1524 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
1525 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
1526 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
1527 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
1528 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
1529 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
1530 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1531 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
1532 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
1533 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
1545 do ix2=ixfmax2,ixfmin2,-1
1546 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
1547 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
1548 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
1551 do ix2=ixfmax2,ixfmin2,-1
1552 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
1553 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
1554 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
1555 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
1556 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
1557 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
1558 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
1572 do ix2=ixfmax2,ixfmin2,-1
1573 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
1574 ix2+1,ixfmin3:ixfmax3,mag(2)) &
1575 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
1576 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
1577 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
1578 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
1581 do ix2=ixfmax2,ixfmin2,-1
1582 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
1583 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
1584 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
1585 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
1586 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
1587 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1588 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
1589 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
1590 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1591 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
1592 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
1593 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
1594 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
1595 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
1596 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1597 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
1598 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
1599 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
1611 do ix2=ixfmin2,ixfmax2
1612 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
1613 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
1614 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
1617 do ix2=ixfmin2,ixfmax2
1618 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
1619 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
1620 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
1621 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
1622 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
1623 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
1624 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
1638 do ix2=ixfmin2,ixfmax2
1639 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
1640 ix2-1,ixfmin3:ixfmax3,mag(2)) &
1641 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
1642 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
1643 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
1644 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
1647 do ix2=ixfmin2,ixfmax2
1648 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
1649 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
1650 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
1651 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
1652 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
1653 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1654 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
1655 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
1656 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1657 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
1658 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
1659 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
1660 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
1661 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
1662 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1663 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
1664 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
1665 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
1680 do ix3=ixfmax3,ixfmin3,-1
1681 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
1682 ixfmin2:ixfmax2,ix3+1,mag(3)) &
1683 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
1684 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
1685 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
1686 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
1689 do ix3=ixfmax3,ixfmin3,-1
1690 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
1691 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
1692 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
1693 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
1694 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
1695 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1696 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
1697 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
1698 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1699 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
1700 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
1701 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
1702 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
1703 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
1704 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
1705 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
1706 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
1707 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
1720 do ix3=ixfmin3,ixfmax3
1721 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
1722 ixfmin2:ixfmax2,ix3-1,mag(3)) &
1723 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
1724 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
1725 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
1726 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
1729 do ix3=ixfmin3,ixfmax3
1730 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
1731 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
1732 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
1733 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
1734 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
1735 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1736 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
1737 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
1738 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1739 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
1740 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
1741 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
1742 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
1743 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
1744 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
1745 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
1746 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
1747 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
1752 call mpistop(
"Special boundary is not defined for this region")
1764 double precision,
intent(in) :: qdt
1765 double precision,
intent(in) :: qt
1766 logical,
intent(inout) :: active
1767 integer :: iigrid, igrid, id
1768 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
1770 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
1771 double precision :: res
1772 double precision,
parameter :: max_residual = 1
d-3
1773 double precision,
parameter :: residual_reduction = 1
d-10
1774 integer,
parameter :: max_its = 50
1775 double precision :: residual_it(max_its), max_divb
1777 mg%operator_type = mg_laplacian
1785 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1786 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1789 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
1790 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1792 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1793 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1796 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
1797 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1801 write(*,*)
"mf_clean_divb_multigrid warning: unknown boundary type"
1802 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1803 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1811 do iigrid = 1, igridstail
1812 igrid = igrids(iigrid);
1815 lvl =
mg%boxes(id)%lvl
1816 nc =
mg%box_size_lvl(lvl)
1822 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
1824 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
1825 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
1830 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
1833 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
1834 if (
mype == 0) print *,
"iteration vs residual"
1837 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
1838 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
1839 if (residual_it(n) < residual_reduction * max_divb)
exit
1841 if (
mype == 0 .and. n > max_its)
then
1842 print *,
"divb_multigrid warning: not fully converged"
1843 print *,
"current amplitude of divb: ", residual_it(max_its)
1844 print *,
"multigrid smallest grid: ", &
1845 mg%domain_size_lvl(:,
mg%lowest_lvl)
1846 print *,
"note: smallest grid ideally has <= 8 cells"
1847 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
1848 print *,
"note: dx/dy/dz should be similar"
1852 call mg_fas_vcycle(
mg, max_res=res)
1853 if (res < max_residual)
exit
1855 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
1860 do iigrid = 1, igridstail
1861 igrid = igrids(iigrid);
1870 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
1874 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
1876 call gradientx(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim),.false.)
1877 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
1885 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
1886 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
1899 integer,
intent(in) :: ixI^L, ixO^L
1900 double precision,
intent(in) :: qt, qdt
1902 double precision,
intent(in) :: wprim(ixI^S,1:nw)
1903 type(state) :: sCT, s
1904 type(ct_velocity) :: vcts
1905 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
1906 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
1916 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
1926 integer,
intent(in) :: ixI^L, ixO^L
1927 double precision,
intent(in) :: qt, qdt
1928 type(state) :: sCT, s
1929 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
1930 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
1932 integer :: hxC^L,ixC^L,jxC^L,ixCm^L
1933 integer :: idim1,idim2,idir,iwdim1,iwdim2
1934 double precision :: circ(ixI^S,1:ndim)
1936 double precision :: jce(ixI^S,sdim:3)
1938 associate(bfaces=>s%ws,x=>s%x)
1953 if (
lvc(idim1,idim2,idir)==1)
then
1955 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
1957 jxc^l=ixc^l+
kr(idim1,^
d);
1958 hxc^l=ixc^l+
kr(idim2,^
d);
1960 fe(ixc^s,idir)=quarter*(fc(ixc^s,iwdim1,idim2)+fc(jxc^s,iwdim1,idim2)&
1961 -fc(ixc^s,iwdim2,idim1)-fc(hxc^s,iwdim2,idim1))
1964 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
1968 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
1979 circ(ixi^s,1:ndim)=zero
1985 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
1989 if(
lvc(idim1,idim2,idir)/=0)
then
1990 hxc^l=ixc^l-
kr(idim2,^
d);
1992 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
1993 +
lvc(idim1,idim2,idir)&
2000 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2002 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2014 integer,
intent(in) :: ixI^L, ixO^L
2015 double precision,
intent(in) :: qt, qdt
2017 double precision,
intent(in) :: wp(ixI^S,1:nw)
2018 type(state) :: sCT, s
2019 type(ct_velocity) :: vcts
2020 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
2021 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
2023 double precision :: circ(ixI^S,1:ndim)
2025 double precision :: ECC(ixI^S,sdim:3)
2027 double precision :: EL(ixI^S),ER(ixI^S)
2029 double precision :: ELC(ixI^S),ERC(ixI^S)
2031 double precision :: jce(ixI^S,sdim:3)
2032 integer :: hxC^L,ixC^L,jxC^L,ixA^L,ixB^L
2033 integer :: idim1,idim2,idir,iwdim1,iwdim2
2035 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm)
2039 do idim1=1,ndim;
do idim2=1,ndim;
do idir=sdim,3
2040 if(
lvc(idim1,idim2,idir)==1)
then
2041 ecc(ixi^s,idir)=ecc(ixi^s,idir)+wp(ixi^s,mag(idim1))*wp(ixi^s,
mom(idim2))
2042 else if(
lvc(idim1,idim2,idir)==-1)
then
2043 ecc(ixi^s,idir)=ecc(ixi^s,idir)-wp(ixi^s,mag(idim1))*wp(ixi^s,
mom(idim2))
2060 if (
lvc(idim1,idim2,idir)==1)
then
2062 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
2064 jxc^l=ixc^l+
kr(idim1,^
d);
2065 hxc^l=ixc^l+
kr(idim2,^
d);
2067 fe(ixc^s,idir)=quarter*&
2068 (fc(ixc^s,iwdim1,idim2)+fc(jxc^s,iwdim1,idim2)&
2069 -fc(ixc^s,iwdim2,idim1)-fc(hxc^s,iwdim2,idim1))
2073 ixamax^
d=ixcmax^
d+
kr(idim1,^
d);
2074 el(ixa^s)=fc(ixa^s,iwdim1,idim2)-ecc(ixa^s,idir)
2075 hxc^l=ixa^l+
kr(idim2,^
d);
2076 er(ixa^s)=fc(ixa^s,iwdim1,idim2)-ecc(hxc^s,idir)
2077 where(vnorm(ixc^s,idim1)>0.d0)
2078 elc(ixc^s)=el(ixc^s)
2079 else where(vnorm(ixc^s,idim1)<0.d0)
2080 elc(ixc^s)=el(jxc^s)
2082 elc(ixc^s)=0.5d0*(el(ixc^s)+el(jxc^s))
2084 hxc^l=ixc^l+
kr(idim2,^
d);
2085 where(vnorm(hxc^s,idim1)>0.d0)
2086 erc(ixc^s)=er(ixc^s)
2087 else where(vnorm(hxc^s,idim1)<0.d0)
2088 erc(ixc^s)=er(jxc^s)
2090 erc(ixc^s)=0.5d0*(er(ixc^s)+er(jxc^s))
2092 fe(ixc^s,idir)=fe(ixc^s,idir)+0.25d0*(elc(ixc^s)+erc(ixc^s))
2095 jxc^l=ixc^l+
kr(idim2,^
d);
2097 ixamax^
d=ixcmax^
d+
kr(idim2,^
d);
2098 el(ixa^s)=-fc(ixa^s,iwdim2,idim1)-ecc(ixa^s,idir)
2099 hxc^l=ixa^l+
kr(idim1,^
d);
2100 er(ixa^s)=-fc(ixa^s,iwdim2,idim1)-ecc(hxc^s,idir)
2101 where(vnorm(ixc^s,idim2)>0.d0)
2102 elc(ixc^s)=el(ixc^s)
2103 else where(vnorm(ixc^s,idim2)<0.d0)
2104 elc(ixc^s)=el(jxc^s)
2106 elc(ixc^s)=0.5d0*(el(ixc^s)+el(jxc^s))
2108 hxc^l=ixc^l+
kr(idim1,^
d);
2109 where(vnorm(hxc^s,idim2)>0.d0)
2110 erc(ixc^s)=er(ixc^s)
2111 else where(vnorm(hxc^s,idim2)<0.d0)
2112 erc(ixc^s)=er(jxc^s)
2114 erc(ixc^s)=0.5d0*(er(ixc^s)+er(jxc^s))
2116 fe(ixc^s,idir)=fe(ixc^s,idir)+0.25d0*(elc(ixc^s)+erc(ixc^s))
2119 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2123 fe(ixc^s,idir)=fe(ixc^s,idir)*qdt*s%dsC(ixc^s,idir)
2138 circ(ixi^s,1:ndim)=zero
2143 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2147 if(
lvc(idim1,idim2,idir)/=0)
then
2148 hxc^l=ixc^l-
kr(idim2,^
d);
2150 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2151 +
lvc(idim1,idim2,idir)&
2158 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
2159 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2161 circ(ixc^s,idim1)=zero
2164 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2177 integer,
intent(in) :: ixI^L, ixO^L
2178 double precision,
intent(in) :: qt, qdt
2179 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
2180 type(state) :: sCT, s
2181 type(ct_velocity) :: vcts
2183 double precision :: vtilL(ixI^S,2)
2184 double precision :: vtilR(ixI^S,2)
2185 double precision :: btilL(ixI^S,ndim)
2186 double precision :: btilR(ixI^S,ndim)
2187 double precision :: cp(ixI^S,2)
2188 double precision :: cm(ixI^S,2)
2189 double precision :: circ(ixI^S,1:ndim)
2191 double precision :: jce(ixI^S,sdim:3)
2192 integer :: hxC^L,ixC^L,ixCp^L,jxC^L,ixCm^L
2193 integer :: idim1,idim2,idir
2195 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
2196 cbarmax=>vcts%cbarmax)
2222 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
2226 idim2=mod(idir+1,3)+1
2228 jxc^l=ixc^l+
kr(idim1,^
d);
2229 ixcp^l=ixc^l+
kr(idim2,^
d);
2232 call reconstruct(ixi^l,ixc^l,idim2,vbarc(ixi^s,idim1,1),&
2233 vtill(ixi^s,2),vtilr(ixi^s,2))
2235 call reconstruct(ixi^l,ixc^l,idim1,vbarc(ixi^s,idim2,2),&
2236 vtill(ixi^s,1),vtilr(ixi^s,1))
2241 call reconstruct(ixi^l,ixc^l,idim2,bfacesct(ixi^s,idim1),&
2242 btill(ixi^s,idim1),btilr(ixi^s,idim1))
2244 call reconstruct(ixi^l,ixc^l,idim1,bfacesct(ixi^s,idim2),&
2245 btill(ixi^s,idim2),btilr(ixi^s,idim2))
2249 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
2250 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
2252 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
2253 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
2257 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
2258 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
2259 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
2260 /(cp(ixc^s,1)+cm(ixc^s,1)) &
2261 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
2262 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
2263 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
2264 /(cp(ixc^s,2)+cm(ixc^s,2))
2267 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2271 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
2285 circ(ixi^s,1:ndim)=zero
2291 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2295 if(
lvc(idim1,idim2,idir)/=0)
then
2296 hxc^l=ixc^l-
kr(idim2,^
d);
2298 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2299 +
lvc(idim1,idim2,idir)&
2306 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
2307 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2309 circ(ixc^s,idim1)=zero
2312 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2324 integer,
intent(in) :: ixI^L, ixO^L
2325 type(state),
intent(in) :: sCT, s
2327 double precision :: jce(ixI^S,sdim:3)
2330 double precision :: jcc(ixI^S,7-2*ndir:3)
2332 double precision :: xs(ixGs^T,1:ndim)
2334 double precision :: eta(ixI^S)
2335 double precision :: gradi(ixGs^T)
2336 integer :: ix^D,ixC^L,ixA^L,ixB^L,idir,idirmin,idim1,idim2
2338 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
2344 if (
lvc(idim1,idim2,idir)==0) cycle
2345 ixcmax^d=ixomax^d+1;
2346 ixcmin^d=ixomin^d+
kr(idir,^d)-2;
2347 ixbmax^d=ixcmax^d-
kr(idir,^d)+1;
2350 xs(ixb^s,:)=x(ixb^s,:)
2351 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
2352 call gradientx(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^l,idim1,gradi,.false.)
2353 if (
lvc(idim1,idim2,idir)==1)
then
2354 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
2356 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
2363 jce(ixi^s,:)=jce(ixi^s,:)*
mf_eta
2371 ixcmin^d=ixomin^d+
kr(idir,^d)-1;
2372 jcc(ixc^s,idir)=0.d0
2374 if({ ix^d==1 .and. ^d==idir | .or.}) cycle
2375 ixamin^d=ixcmin^d+ix^d;
2376 ixamax^d=ixcmax^d+ix^d;
2377 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
2379 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
2380 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
2391 integer,
intent(in) :: ixo^
l
2394 integer :: fxo^
l, gxo^
l, hxo^
l, jxo^
l, kxo^
l, idim
2396 associate(w=>s%w, ws=>s%ws)
2403 hxo^
l=ixo^
l-
kr(idim,^
d);
2406 w(ixo^s,mag(idim))=half/s%surface(ixo^s,idim)*&
2407 (ws(ixo^s,idim)*s%surfaceC(ixo^s,idim)&
2408 +ws(hxo^s,idim)*s%surfaceC(hxo^s,idim))
2452 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
2453 double precision,
intent(inout) :: ws(ixis^s,1:nws)
2454 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2456 double precision :: adummy(ixis^s,1:3)
2465 double precision :: sum_jbb_ipe, sum_j_ipe, sum_l_ipe, f_i_ipe, volume_pe
2466 double precision :: sum_jbb, sum_j, sum_l, f_i, volume, cw_sin_theta
2467 integer :: iigrid, igrid, ix^
d
2468 integer :: amode, istatus(mpi_status_size)
2469 integer,
save :: fhmf
2470 character(len=800) :: filename,filehead
2471 character(len=800) :: line,datastr
2472 logical :: patchwi(ixg^t)
2473 logical,
save :: logmfopened=.false.
2480 do iigrid=1,igridstail; igrid=igrids(iigrid);
2485 ps(igrid)%x,1,patchwi)
2487 ps(igrid)%x,2,patchwi)
2489 ps(igrid)%x,3,patchwi)
2491 ps(igrid)%x,4,patchwi)
2493 call mpi_reduce(sum_jbb_ipe,sum_jbb,1,mpi_double_precision,&
2495 call mpi_reduce(sum_j_ipe,sum_j,1,mpi_double_precision,mpi_sum,0,&
2497 call mpi_reduce(f_i_ipe,f_i,1,mpi_double_precision,mpi_sum,0,&
2499 call mpi_reduce(sum_l_ipe,sum_l,1,mpi_double_precision,mpi_sum,0,&
2501 call mpi_reduce(volume_pe,volume,1,mpi_double_precision,mpi_sum,0,&
2507 cw_sin_theta = sum_jbb/sum_j
2513 if(.not.logmfopened)
then
2515 write(filename,
"(a,a)") trim(
base_filename),
"_mf_metrics.csv"
2519 open(unit=20,file=trim(filename),status=
'replace')
2520 close(20, status=
'delete')
2523 amode=ior(mpi_mode_create,mpi_mode_wronly)
2524 amode=ior(amode,mpi_mode_append)
2525 call mpi_file_open(mpi_comm_self,filename,amode,mpi_info_null,fhmf,
ierrmpi)
2527 filehead=
" it,time,CW_sin_theta,current,Lorenz_force,f_i"
2529 call mpi_file_write(fhmf,filehead,len_trim(filehead), &
2530 mpi_character,istatus,
ierrmpi)
2531 call mpi_file_write(fhmf,achar(10),1,mpi_character,istatus,
ierrmpi)
2535 write(datastr,
'(i6,a)')
it,
','
2536 line=trim(line)//trim(datastr)
2538 line=trim(line)//trim(datastr)
2539 write(datastr,
'(es13.6,a)') cw_sin_theta,
','
2540 line=trim(line)//trim(datastr)
2541 write(datastr,
'(es13.6,a)') sum_j,
','
2542 line=trim(line)//trim(datastr)
2543 write(datastr,
'(es13.6,a)') sum_l,
','
2544 line=trim(line)//trim(datastr)
2545 write(datastr,
'(es13.6)') f_i
2546 line=trim(line)//trim(datastr)//new_line(
'A')
2547 call mpi_file_write(fhmf,line,len_trim(line),mpi_character,istatus,
ierrmpi)
2549 call mpi_file_close(fhmf,
ierrmpi)
2559 integer,
intent(in) :: ixI^L,ixO^L
2560 double precision,
intent(in):: w(ixI^S,nw),x(ixI^S,1:ndim)
2561 double precision,
intent(inout) :: volume_pe
2562 logical,
intent(out) :: patchwi(ixI^S)
2564 double precision :: xO^L
2567 {xomin^d = xprobmin^d + 0.05d0*(xprobmax^d-xprobmin^d)\}
2568 {xomax^d = xprobmax^d - 0.05d0*(xprobmax^d-xprobmin^d)\}
2570 xomin^nd = xprobmin^nd
2575 {
do ix^db=ixomin^db,ixomax^db\}
2576 if({ x(ix^dd,^d) > xomin^d .and. x(ix^dd,^d) < xomax^d | .and. })
then
2577 patchwi(ix^d)=.true.
2578 volume_pe=volume_pe+
block%dvolume(ix^d)
2580 patchwi(ix^d)=.false.
2589 integer,
intent(in) :: ixi^
l,ixo^
l,iw
2590 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2591 double precision :: w(ixi^s,nw+
nwauxio)
2592 logical,
intent(in) :: patchwi(ixi^s)
2594 double precision,
dimension(ixI^S,7-2*ndir:3) :: current
2595 double precision,
dimension(ixI^S,1:ndir) :: bvec,qvec
2597 integer :: ix^
d,idirmin0,idirmin,idir,jdir,kdir
2603 bvec(ixo^s,:)=w(ixo^s,mag(:))
2606 qvec(ixo^s,1:
ndir)=zero
2607 do idir=1,
ndir;
do jdir=idirmin,3;
do kdir=1,
ndir
2608 if(
lvc(idir,jdir,kdir)/=0)
then
2609 if(
lvc(idir,jdir,kdir)==1)
then
2610 qvec(ixo^s,idir)=qvec(ixo^s,idir)+current(ixo^s,jdir)*bvec(ixo^s,kdir)
2612 qvec(ixo^s,idir)=qvec(ixo^s,idir)-current(ixo^s,jdir)*bvec(ixo^s,kdir)
2615 end do;
end do;
end do
2617 {
do ix^db=ixomin^db,ixomax^db\}
2618 if(patchwi(ix^d))
then
2619 bm2=sum(bvec(ix^d,:)**2)
2620 if(bm2/=0.d0) bm2=1.d0/bm2
2622 bm2)*block%dvolume(ix^d)
2628 {
do ix^db=ixomin^db,ixomax^db\}
2636 {
do ix^db=ixomin^db,ixomax^db\}
2641 bvec(ixo^s,:)=w(ixo^s,mag(:))
2644 qvec(ixo^s,1:ndir)=zero
2645 do idir=1,ndir;
do jdir=idirmin,3;
do kdir=1,ndir
2646 if(lvc(idir,jdir,kdir)/=0)
then
2647 if(lvc(idir,jdir,kdir)==1)
then
2648 qvec(ixo^s,idir)=qvec(ixo^s,idir)+current(ixo^s,jdir)*bvec(ixo^s,kdir)
2650 qvec(ixo^s,idir)=qvec(ixo^s,idir)-current(ixo^s,jdir)*bvec(ixo^s,kdir)
2653 end do;
end do;
end do
2655 {
do ix^db=ixomin^db,ixomax^db\}
2657 sqrt(sum(qvec(ix^d,:)**2))*block%dvolume(ix^d)
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
subroutine b_from_vector_potentiala(ixIsL, ixIL, ixOL, ws, x, A)
calculate magnetic field from vector potential A at cell edges
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...
Module with basic grid data structures.
type(tree_node_ptr), dimension(:,:), allocatable, save igrid_to_node
Array to go from an [igrid, ipe] index to a node pointer.
integer, dimension(:), allocatable, public mag
Indices of the magnetic field.
subroutine, public get_divb(w, ixIL, ixOL, divb, fourthorder)
Calculate div B within ixO.
Module with geometry-related routines (e.g., divergence, curl)
integer, parameter cylindrical
subroutine gradient(q, ixIL, ixOL, idir, gradq)
Calculate gradient of a scalar q within ixL in direction idir.
subroutine curlvector(qvec, ixIL, ixOL, curlvec, idirmin, idirmin0, ndir0, fourthorder)
Calculate curl of a vector qvec within ixL Options to employ standard second order CD evaluations use...
subroutine gradients(q, ixIL, ixOL, idir, gradq)
Calculate gradient of a scalar q within ixL in direction idir first use limiter to go from cell cente...
subroutine gradientx(q, x, ixIL, ixOL, idir, gradq, fourth_order)
Calculate gradient of a scalar q in direction idir at cell interfaces.
update ghost cells of all blocks including physical boundaries
integer, dimension(-1:2^d &,-1:1^d &), target type_recv_srl_f
integer, dimension(-1:1^d &, 0:3^d &), target type_recv_p_p1
integer, dimension(-1:1^d &, 0:3^d &), target type_send_p_p1
integer, dimension(-1:2^d &,-1:1^d &), target type_send_srl_p1
integer, dimension(-1:1^d &, 0:3^d &), target type_send_p_f
integer, dimension(:^d &,:^d &), pointer type_recv_srl
subroutine create_bc_mpi_datatype(nwstart, nwbc)
integer, dimension(-1:2^d &,-1:1^d &), target type_recv_srl_p1
integer, dimension(:^d &,:^d &), pointer type_send_srl
integer, dimension(-1:1^d &, 0:3^d &), target type_recv_r_f
integer, dimension(:^d &,:^d &), pointer type_recv_r
integer, dimension(:^d &,:^d &), pointer type_send_r
integer, dimension(-1:1^d &, 0:3^d &), target type_recv_r_p1
integer, dimension(-1:1^d &, 0:3^d &), target type_recv_p_f
subroutine getbc(time, qdt, psb, nwstart, nwbc, req_diag)
do update ghost cells of all blocks including physical boundaries
integer, dimension(-1:2^d &,-1:1^d &), target type_send_srl_f
integer, dimension(-1:1^d &,-1:1^d &), target type_send_r_p1
integer, dimension(:^d &,:^d &), pointer type_recv_p
integer, dimension(:^d &,:^d &), pointer type_send_p
integer, dimension(-1:1^d &,-1:1^d &), target type_send_r_f
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.
double precision dtdiffpar
For resistive MHD, the time step is also limited by the diffusion time: .
character(len=std_len) typegrad
double precision unit_charge
Physical scaling factor for charge.
integer ixghi
Upper index of grid block arrays.
integer, dimension(3, 3, 3) lvc
Levi-Civita tensor.
double precision unit_time
Physical scaling factor for time.
double precision unit_density
Physical scaling factor for density.
integer, parameter unitpar
file handle for IO
integer, parameter bc_asymm
double precision global_time
The global simulation time.
double precision unit_mass
Physical scaling factor for mass.
integer, dimension(3, 3) kr
Kronecker delta tensor.
integer it
Number of time steps taken.
integer, dimension(:, :), allocatable typeboundary
Array indicating the type of boundary condition per variable and per physical boundary.
double precision unit_numberdensity
Physical scaling factor for number density.
double precision unit_pressure
Physical scaling factor for pressure.
integer, parameter ndim
Number of spatial dimensions for grid variables.
double precision unit_length
Physical scaling factor for length.
logical stagger_grid
True for using stagger grid.
double precision cmax_global
global fastest wave speed needed in fd scheme and glm method
logical use_particles
Use particles module or not.
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer icomm
The MPI communicator.
double precision bdip
amplitude of background dipolar, quadrupolar, octupolar, user's field
integer mype
The rank of the current MPI task.
integer, dimension(:), allocatable, parameter d
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ixm
the mesh range of a physical block without ghost cells
integer ierrmpi
A global MPI error return code.
logical slab
Cartesian geometry or not.
integer, parameter bc_periodic
integer, parameter bc_special
boundary condition types
double precision unit_magneticfield
Physical scaling factor for magnetic field.
integer nwauxio
Number of auxiliary variables that are only included in output.
double precision unit_velocity
Physical scaling factor for velocity.
character(len=std_len) restart_from_file
If not 'unavailable', resume from snapshot with this base file name.
double precision c_norm
Normalised speed of light.
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
double precision unit_temperature
Physical scaling factor for temperature.
integer, parameter bc_cont
logical si_unit
Use SI units (.true.) or use cgs units (.false.)
double precision, dimension(:,:), allocatable dx
integer nghostcells
Number of ghost cells surrounding a grid.
integer, parameter bc_symm
character(len= *), parameter undefined
logical need_global_cmax
need global maximal wave speed
logical use_multigrid
Use multigrid (only available in 2D and 3D)
logical slab_uniform
uniform Cartesian geometry or not (stretched Cartesian)
character(len=std_len) base_filename
Base file name for simulation output, which will be followed by a number.
integer r_
Indices for cylindrical coordinates FOR TESTS, negative value when not used:
logical record_electric_field
True for record electric field.
double precision, dimension(ndim) dxlevel
integer, parameter ixglo
Lower index of grid block arrays (always 1)
double precision, public mf_nu
viscosity coefficient in s cm^-2 for solar corona (Cheung 2012 ApJ)
logical, public, protected mf_divb_4thorder
Whether divB is computed with a fourth order approximation.
subroutine frictional_velocity(w, x, ixIL, ixOL)
subroutine mf_get_ct_velocity(vcts, wLp, wRp, ixIL, ixOL, idim, cmax, cmin)
prepare velocities for ct methods
subroutine add_source_hyperres(qdt, ixIL, ixOL, wCT, w, x)
Add Hyper-resistive source to w within ixO Uses 9 point stencil (4 neighbours) in each direction.
subroutine, public mf_to_primitive(ixIL, ixOL, w, x)
Transform conservative variables into primitive ones.
subroutine, public mf_phys_init()
subroutine mf_get_flux(wC, w, x, ixIL, ixOL, idim, f)
Calculate fluxes within ixO^L.
subroutine add_source_glm(qdt, ixIL, ixOL, wCT, w, x)
subroutine mf_check_params
subroutine mf_add_source_geom(qdt, dtfactor, ixIL, ixOL, wCT, wprim, w, x)
subroutine add_source_janhunen(qdt, ixIL, ixOL, wCT, w, x)
subroutine, public mf_face_to_center(ixOL, s)
calculate cell-center values from face-center values
subroutine mf_modify_wlr(ixIL, ixOL, qt, wLC, wRC, wLp, wRp, s, idir)
logical, public, protected mf_record_electric_field
set to true if need to record electric field on cell edges
subroutine add_source_linde(qdt, ixIL, ixOL, wCT, w, x)
subroutine update_faces_hll(ixIL, ixOL, qt, qdt, fE, sCT, s, vcts)
update faces
subroutine, public b_from_vector_potential(ixIsL, ixIL, ixOL, ws, x)
calculate magnetic field from vector potential
logical, public, protected clean_initial_divb
clean divb in the initial condition
subroutine fixdivb_boundary(ixGL, ixOL, w, x, iB)
logical, public divbwave
Add divB wave in Roe solver.
subroutine mf_get_cmax(w, x, ixIL, ixOL, idim, cmax)
Calculate cmax_idim=csound+abs(v_idim) within ixO^L.
subroutine mf_get_p_total(w, x, ixIL, ixOL, p)
Calculate total pressure within ixO^L including magnetic pressure.
double precision, public mf_vmax
maximal limit of magnetofrictional velocity in cm s^-1 (Pomoell 2019 A&A)
logical, public, protected mf_glm
Whether GLM-MHD is used.
subroutine get_resistive_electric_field(ixIL, ixOL, sCT, s, jce)
calculate eta J at cell edges
double precision, public mf_eta_hyper
The hyper-resistivity.
subroutine add_source_res2(qdt, ixIL, ixOL, wCT, w, x)
Add resistive source to w within ixO Uses 5 point stencil (2 neighbours) in each direction,...
subroutine, public get_normalized_divb(w, ixIL, ixOL, divb)
get dimensionless div B = |divB| * volume / area / |B|
subroutine add_source_res1(qdt, ixIL, ixOL, wCT, w, x)
Add resistive source to w within ixO Uses 3 point stencil (1 neighbour) in each direction,...
subroutine, public get_current(w, ixIL, ixOL, idirmin, current, fourthorder)
Calculate idirmin and the idirmin:3 components of the common current array make sure that dxlevel(^D)...
subroutine mf_get_cbounds(wLC, wRC, wLp, wRp, x, ixIL, ixOL, idim, Hspeed, cmax, cmin)
Estimating bounds for the minimum and maximum signal velocities.
double precision function integral_grid_mf(ixIL, ixOL, w, x, iw, patchwi)
subroutine mf_velocity_update(qt, psa)
Add global source terms to update frictional velocity on complete domain.
double precision function, dimension(ixo^s) mf_mag_en(w, ixIL, ixOL)
Compute evolving magnetic energy.
double precision, public mf_glm_alpha
GLM-MHD parameter: ratio of the diffusive and advective time scales for div b taking values within [0...
subroutine mf_add_source(qdt, dtfactor, ixIL, ixOL, wCT, wCTprim, w, x, qsourcesplit, active)
w[iws]=w[iws]+qdt*S[iws,wCT] where S is the source based on wCT within ixO
subroutine mf_get_dt(w, ixIL, ixOL, dtnew, dxD, x)
If resistivity is not zero, check diffusion time limit for dt.
subroutine mask_inner(ixIL, ixOL, w, x, patchwi, volume_pe)
logical, dimension(2 *^nd), public, protected boundary_divbfix
To control divB=0 fix for boundary.
subroutine update_faces_average(ixIL, ixOL, qt, qdt, fC, fE, sCT, s)
get electric field though averaging neighors to update faces in CT
character(len=std_len), public, protected type_ct
Method type of constrained transport.
double precision function, dimension(ixo^s), public mf_mag_en_all(w, ixIL, ixOL)
Compute 2 times total magnetic energy.
character(len=std_len), public, protected typedivbfix
Method type to clean divergence of B.
subroutine, public mf_to_conserved(ixIL, ixOL, w, x)
Transform primitive variables into conservative ones.
subroutine mf_boundary_adjust(igrid, psb)
integer, dimension(2 *^nd), public, protected boundary_divbfix_skip
To skip * layer of ghost cells during divB=0 fix for boundary.
subroutine add_source_powel(qdt, ixIL, ixOL, wCT, w, x)
Add divB related sources to w within ixO corresponding to Powel.
double precision, dimension(2 *^nd), public mf_decay_scale
decay scale of frictional velocity near boundaries
subroutine, public record_force_free_metrics()
subroutine mf_write_info(fh)
Write this module's parameters to a snapsoht.
logical, public, protected mf_4th_order
MHD fourth order.
integer, public, protected psi_
Indices of the GLM psi.
integer, dimension(:), allocatable, public, protected mom
Indices of the momentum density.
subroutine, public mf_clean_divb_multigrid(qdt, qt, active)
logical, public, protected mf_particles
Whether particles module is added.
double precision function, dimension(ixo^s) mf_mag_i_all(w, ixIL, ixOL, idir)
Compute full magnetic field by direction.
subroutine, public mf_get_v(w, x, ixIL, ixOL, v)
Calculate v vector.
double precision, public mf_eta
The resistivity.
subroutine update_faces_contact(ixIL, ixOL, qt, qdt, wp, fC, fE, sCT, s, vcts)
update faces using UCT contact mode by Gardiner and Stone 2005 JCP 205, 509
logical, public, protected source_split_divb
Whether divB cleaning sources are added splitting from fluid solver.
double precision, public, protected he_abundance
Helium abundance over Hydrogen.
subroutine mf_update_faces(ixIL, ixOL, qt, qdt, wprim, fC, fE, sCT, s, vcts)
subroutine, public mf_get_v_idim(w, x, ixIL, ixOL, idim, v)
Calculate v component.
subroutine mf_physical_units()
Module to couple the octree-mg library to AMRVAC. This file uses the VACPP preprocessor,...
type(mg_t) mg
Data structure containing the multigrid tree.
Module containing all the particle routines.
subroutine particles_init()
Initialize particle data and parameters.
This module defines the procedures of a physics module. It contains function pointers for the various...
procedure(sub_get_ct_velocity), pointer phys_get_ct_velocity
procedure(sub_convert), pointer phys_to_primitive
integer, parameter flux_tvdlf
Indicates the flux should be treated with tvdlf.
procedure(sub_write_info), pointer phys_write_info
procedure(sub_get_flux), pointer phys_get_flux
logical phys_req_diagonal
Whether the physics routines require diagonal ghost cells, for example for computing a curl.
procedure(sub_get_cbounds), pointer phys_get_cbounds
procedure(sub_get_dt), pointer phys_get_dt
procedure(sub_add_source_geom), pointer phys_add_source_geom
procedure(sub_check_params), pointer phys_check_params
integer, parameter flux_default
Indicates a normal flux.
integer, dimension(:, :), allocatable flux_type
Array per direction per variable, which can be used to specify that certain fluxes have to be treated...
procedure(sub_update_faces), pointer phys_update_faces
procedure(sub_convert), pointer phys_to_conserved
character(len=name_len) physics_type
String describing the physics type of the simulation.
procedure(sub_clean_divb), pointer phys_clean_divb
procedure(sub_boundary_adjust), pointer phys_boundary_adjust
procedure(sub_global_source), pointer phys_global_source_after
procedure(sub_add_source), pointer phys_add_source
procedure(sub_face_to_center), pointer phys_face_to_center
procedure(sub_modify_wlr), pointer phys_modify_wlr
procedure(sub_get_cmax), pointer phys_get_cmax
procedure(sub_get_v), pointer phys_get_v
logical phys_energy
Solve energy equation or not.
procedure(sub_special_advance), pointer phys_special_advance
Module with all the methods that users can customize in AMRVAC.
procedure(special_resistivity), pointer usr_special_resistivity
procedure(set_electric_field), pointer usr_set_electric_field
The data structure that contains information about a tree node/grid block.