8 double precision,
public ::
mf_nu = 1.d-15
11 double precision,
public ::
mf_vmax = 3.d6
20 logical,
public,
protected ::
mf_glm = .false.
36 integer,
allocatable,
public,
protected ::
mom(:)
39 integer,
allocatable,
public,
protected ::
mag(:)
42 integer,
public,
protected ::
psi_
45 double precision,
public ::
mf_eta = 0.0d0
51 character(len=std_len),
public,
protected ::
typedivbfix =
'ct'
54 character(len=std_len),
public,
protected ::
type_ct =
'average'
63 double precision :: divbdiff = 0.8d0
66 character(len=std_len) :: typedivbdiff =
'all'
69 logical :: compactres = .false.
87 integer,
parameter :: divb_none = 0
88 integer,
parameter :: divb_multigrid = -1
89 integer,
parameter :: divb_glm = 1
90 integer,
parameter :: divb_powel = 2
91 integer,
parameter :: divb_janhunen = 3
92 integer,
parameter :: divb_linde = 4
93 integer,
parameter :: divb_lindejanhunen = 5
94 integer,
parameter :: divb_lindepowel = 6
95 integer,
parameter :: divb_lindeglm = 7
96 integer,
parameter :: divb_ct = 8
119 subroutine mf_read_params(files)
122 character(len=*),
intent(in) :: files(:)
133 do n = 1,
size(files)
134 open(
unitpar, file=trim(files(n)), status=
"old")
135 read(
unitpar, mf_list,
end=111)
139 end subroutine mf_read_params
144 integer,
intent(in) :: fh
145 integer,
parameter :: n_par = 1
146 double precision :: values(n_par)
147 character(len=name_len) :: names(n_par)
148 integer,
dimension(MPI_STATUS_SIZE) :: st
151 call mpi_file_write(fh, n_par, 1, mpi_integer, st, er)
155 call mpi_file_write(fh, values, n_par, mpi_double_precision, st, er)
156 call mpi_file_write(fh, names, n_par * name_len, mpi_character, st, er)
161 double precision,
intent(in) :: x(ixI^S,1:ndim)
162 double precision,
intent(inout) :: fC(ixI^S,1:nwflux,1:ndim), wnew(ixI^S,1:nw)
163 integer,
intent(in) :: ixI^L, ixO^L
164 integer,
intent(in) :: idim
165 integer :: hxO^L, kxC^L, iw
166 double precision :: inv_volume(ixI^S)
191 type_divb = divb_none
194 type_divb = divb_multigrid
196 mg%operator_type = mg_laplacian
203 case (
'powel',
'powell')
204 type_divb = divb_powel
206 type_divb = divb_janhunen
208 type_divb = divb_linde
209 case (
'lindejanhunen')
210 type_divb = divb_lindejanhunen
212 type_divb = divb_lindepowel
216 type_divb = divb_lindeglm
221 call mpistop(
'Unknown divB fix')
229 mom(:) = var_set_momentum(
ndir)
237 allocate(start_indices(number_species),stop_indices(number_species))
239 start_indices(1)=
mag(1)
242 psi_ = var_set_fluxvar(
'psi',
'psi', need_bc=.false.)
251 stop_indices(1)=nwflux
257 allocate(iw_vector(nvector))
258 iw_vector(1) =
mom(1) - 1
259 iw_vector(2) =
mag(1) - 1
266 call mpistop(
"phys_check error: flux_type has wrong shape")
287 if(type_divb==divb_glm)
then
302 write(*,*)
'*****Using particles: particles_eta, particles_etah :', particles_eta, particles_etah
332 double precision :: mp,kB,miu0,c_lightspeed
392 integer,
intent(in) :: ixi^
l, ixo^
l
393 double precision,
intent(inout) :: w(ixi^s, nw)
394 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
402 integer,
intent(in) :: ixi^
l, ixo^
l
403 double precision,
intent(inout) :: w(ixi^s, nw)
404 double precision,
intent(in) :: x(ixi^s, 1:
ndim)
413 integer,
intent(in) :: ixi^
l, ixo^
l
414 double precision,
intent(in) :: w(ixi^s,nw), x(ixi^s,1:
ndim)
415 double precision,
intent(out) :: v(ixi^s,
ndir)
420 v(ixo^s,idir) = w(ixo^s,
mom(idir))
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(out) :: v(ixi^s)
433 v(ixo^s) = w(ixo^s,
mom(idim))
441 integer,
intent(in) :: ixI^L, ixO^L, idim
442 double precision,
intent(in) :: w(ixI^S, nw), x(ixI^S,1:ndim)
443 double precision,
intent(inout) :: cmax(ixI^S)
445 cmax(ixo^s)=abs(w(ixo^s,
mom(idim)))+one
450 subroutine mf_get_cbounds(wLC,wRC,wLp,wRp,x,ixI^L,ixO^L,idim,Hspeed,cmax,cmin)
454 integer,
intent(in) :: ixI^L, ixO^L, idim
455 double precision,
intent(in) :: wLC(ixI^S, nw), wRC(ixI^S, nw)
456 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
457 double precision,
intent(in) :: x(ixI^S,1:ndim)
458 double precision,
intent(inout) :: cmax(ixI^S,1:number_species)
459 double precision,
intent(inout),
optional :: cmin(ixI^S,1:number_species)
460 double precision,
intent(in) :: Hspeed(ixI^S,1:number_species)
462 double precision,
dimension(ixI^S) :: tmp1
464 tmp1(ixo^s)=0.5d0*(wlc(ixo^s,
mom(idim))+wrc(ixo^s,
mom(idim)))
465 if(
present(cmin))
then
466 cmax(ixo^s,1)=max(tmp1(ixo^s)+one,zero)
467 cmin(ixo^s,1)=min(tmp1(ixo^s)-one,zero)
469 cmax(ixo^s,1)=abs(tmp1(ixo^s))+one
478 integer,
intent(in) :: ixI^L, ixO^L, idim
479 double precision,
intent(in) :: wLp(ixI^S, nw), wRp(ixI^S, nw)
480 double precision,
intent(in) :: cmax(ixI^S)
481 double precision,
intent(in),
optional :: cmin(ixI^S)
482 type(ct_velocity),
intent(inout):: vcts
484 integer :: idimE,idimN
490 if(.not.
allocated(vcts%vnorm))
allocate(vcts%vnorm(ixi^s,1:
ndim))
492 vcts%vnorm(ixo^s,idim)=0.5d0*(wlp(ixo^s,
mom(idim))+wrp(ixo^s,
mom(idim)))
494 if(.not.
allocated(vcts%vbarC))
then
495 allocate(vcts%vbarC(ixi^s,1:
ndir,2),vcts%vbarLC(ixi^s,1:
ndir,2),vcts%vbarRC(ixi^s,1:
ndir,2))
496 allocate(vcts%cbarmin(ixi^s,1:
ndim),vcts%cbarmax(ixi^s,1:
ndim))
499 if(
present(cmin))
then
500 vcts%cbarmin(ixo^s,idim)=max(-cmin(ixo^s),zero)
501 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
503 vcts%cbarmax(ixo^s,idim)=max( cmax(ixo^s),zero)
504 vcts%cbarmin(ixo^s,idim)=vcts%cbarmax(ixo^s,idim)
507 idimn=mod(idim,
ndir)+1
508 idime=mod(idim+1,
ndir)+1
510 vcts%vbarLC(ixo^s,idim,1)=wlp(ixo^s,
mom(idimn))
511 vcts%vbarRC(ixo^s,idim,1)=wrp(ixo^s,
mom(idimn))
512 vcts%vbarC(ixo^s,idim,1)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,1) &
513 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
514 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
516 vcts%vbarLC(ixo^s,idim,2)=wlp(ixo^s,
mom(idime))
517 vcts%vbarRC(ixo^s,idim,2)=wrp(ixo^s,
mom(idime))
518 vcts%vbarC(ixo^s,idim,2)=(vcts%cbarmax(ixo^s,idim)*vcts%vbarLC(ixo^s,idim,2) &
519 +vcts%cbarmin(ixo^s,idim)*vcts%vbarRC(ixo^s,idim,1))&
520 /(vcts%cbarmax(ixo^s,idim)+vcts%cbarmin(ixo^s,idim))
522 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
531 integer,
intent(in) :: ixI^L, ixO^L
532 double precision,
intent(in) :: w(ixI^S,nw)
533 double precision,
intent(in) :: x(ixI^S,1:ndim)
534 double precision,
intent(out) :: p(ixI^S)
536 p(ixo^s) = 0.5d0 * sum(w(ixo^s,
mag(:))**2, dim=ndim+1)
546 integer,
intent(in) :: ixI^L, ixO^L, idim
548 double precision,
intent(in) :: wC(ixI^S,nw)
550 double precision,
intent(in) :: w(ixI^S,nw)
551 double precision,
intent(in) :: x(ixI^S,1:ndim)
552 double precision,
intent(out) :: f(ixI^S,nwflux)
565 f(ixo^s,
mag(idir))=w(ixo^s,
psi_)
567 f(ixo^s,
mag(idir))=zero
570 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))
585 double precision,
intent(in) :: qt
586 type(state),
target :: psa(max_blocks)
588 integer :: iigrid,igrid
589 logical :: stagger_flag
590 logical :: firstmf=.true.
605 do iigrid=1,igridstail_active; igrid=igrids_active(iigrid);
634 subroutine mf_add_source(qdt,ixI^L,ixO^L,wCT,w,x,qsourcesplit,active,wCTprim)
637 integer,
intent(in) :: ixI^L, ixO^L
638 double precision,
intent(in) :: qdt
639 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
640 double precision,
intent(inout) :: w(ixI^S,1:nw)
641 logical,
intent(in) :: qsourcesplit
642 logical,
intent(inout) :: active
643 double precision,
intent(in),
optional :: wCTprim(ixI^S,1:nw)
645 if (.not. qsourcesplit)
then
648 if (abs(
mf_eta)>smalldouble)
then
663 select case (type_divb)
678 case (divb_lindejanhunen)
682 case (divb_lindepowel)
692 case (divb_multigrid)
695 call mpistop(
'Unknown divB fix')
699 select case (type_divb)
714 case (divb_lindejanhunen)
718 case (divb_lindepowel)
728 case (divb_multigrid)
731 call mpistop(
'Unknown divB fix')
741 integer,
intent(in) :: ixI^L, ixO^L
742 double precision,
intent(in) :: x(ixI^S,1:ndim)
743 double precision,
intent(inout) :: w(ixI^S,1:nw)
745 double precision :: xmin(ndim),xmax(ndim)
746 double precision :: decay(ixO^S)
747 double precision :: current(ixI^S,7-2*ndir:3),tmp(ixO^S)
748 integer :: ix^D, idirmin,idir,jdir,kdir
754 if(
block%is_physical_boundary(2*^d-1))
then
755 current(ixomin^d^d%ixO^s,:)=current(ixomin^d+1^d%ixO^s,:)
757 if(
block%is_physical_boundary(2*^d))
then
758 current(ixomax^d^d%ixO^s,:)=current(ixomax^d-1^d%ixO^s,:)
763 do idir=1,ndir;
do jdir=idirmin,3;
do kdir=1,ndir
764 if(
lvc(idir,jdir,kdir)/=0)
then
765 if(
lvc(idir,jdir,kdir)==1)
then
766 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))+current(ixo^s,jdir)*w(ixo^s,
mag(kdir))
768 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))-current(ixo^s,jdir)*w(ixo^s,
mag(kdir))
771 end do;
end do;
end do
773 tmp(ixo^s)=sum(w(ixo^s,
mag(:))**2,dim=ndim+1)
775 where(tmp(ixo^s)/=0.d0)
776 tmp(ixo^s)=1.d0/(tmp(ixo^s)*
mf_nu)
780 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))*tmp(ixo^s)
784 ^d&xmin(^d)=xprobmin^d\
785 ^d&xmax(^d)=xprobmax^d\
795 tmp(ixo^s)=sqrt(sum(w(ixo^s,
mom(:))**2,dim=ndim+1))/
mf_vmax+1.d-12
796 tmp(ixo^s)=dtanh(tmp(ixo^s))/tmp(ixo^s)
798 w(ixo^s,
mom(idir))=w(ixo^s,
mom(idir))*tmp(ixo^s)*decay(ixo^s)
812 integer,
intent(in) :: ixI^L, ixO^L
813 double precision,
intent(in) :: qdt
814 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
815 double precision,
intent(inout) :: w(ixI^S,1:nw)
816 integer :: ixA^L,idir,jdir,kdir,idirmin,idim,jxO^L,hxO^L,ix
817 integer :: lxO^L, kxO^L
819 double precision :: tmp(ixI^S),tmp2(ixI^S)
822 double precision :: current(ixI^S,7-2*ndir:3),eta(ixI^S)
823 double precision :: gradeta(ixI^S,1:ndim), Bf(ixI^S,1:ndir)
832 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
833 call mpistop(
"Error in add_source_res1: Non-conforming input limits")
840 gradeta(ixo^s,1:ndim)=zero
845 call gradient(eta,ixi^l,ixo^l,idim,tmp)
846 gradeta(ixo^s,idim)=tmp(ixo^s)
850 bf(ixi^s,1:ndir)=wct(ixi^s,
mag(1:ndir))
856 tmp2(ixi^s)=bf(ixi^s,idir)
858 lxo^l=ixo^l+2*
kr(idim,^
d);
859 jxo^l=ixo^l+
kr(idim,^
d);
860 hxo^l=ixo^l-
kr(idim,^
d);
861 kxo^l=ixo^l-2*
kr(idim,^
d);
862 tmp(ixo^s)=tmp(ixo^s)+&
863 (-tmp2(lxo^s)+16.0d0*tmp2(jxo^s)-30.0d0*tmp2(ixo^s)+16.0d0*tmp2(hxo^s)-tmp2(kxo^s)) &
868 tmp2(ixi^s)=bf(ixi^s,idir)
870 jxo^l=ixo^l+
kr(idim,^
d);
871 hxo^l=ixo^l-
kr(idim,^
d);
872 tmp(ixo^s)=tmp(ixo^s)+&
873 (tmp2(jxo^s)-2.0d0*tmp2(ixo^s)+tmp2(hxo^s))/
dxlevel(idim)**2
878 tmp(ixo^s)=tmp(ixo^s)*eta(ixo^s)
882 do jdir=1,ndim;
do kdir=idirmin,3
883 if (
lvc(idir,jdir,kdir)/=0)
then
884 if (
lvc(idir,jdir,kdir)==1)
then
885 tmp(ixo^s)=tmp(ixo^s)-gradeta(ixo^s,jdir)*current(ixo^s,kdir)
887 tmp(ixo^s)=tmp(ixo^s)+gradeta(ixo^s,jdir)*current(ixo^s,kdir)
894 w(ixo^s,
mag(idir))=w(ixo^s,
mag(idir))+qdt*tmp(ixo^s)
907 integer,
intent(in) :: ixI^L, ixO^L
908 double precision,
intent(in) :: qdt
909 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
910 double precision,
intent(inout) :: w(ixI^S,1:nw)
913 double precision :: current(ixI^S,7-2*ndir:3),eta(ixI^S),curlj(ixI^S,1:3)
914 double precision :: tmpvec(ixI^S,1:3)
915 integer :: ixA^L,idir,idirmin,idirmin1
922 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
923 call mpistop(
"Error in add_source_res2: Non-conforming input limits")
937 tmpvec(ixa^s,1:ndir)=zero
939 tmpvec(ixa^s,idir)=current(ixa^s,idir)*eta(ixa^s)
942 call curlvector(tmpvec,ixi^l,ixo^l,curlj,idirmin1,1,3)
944 if(ndim==2.and.ndir==3)
then
946 w(ixo^s,
mag(ndir)) = w(ixo^s,
mag(ndir))-qdt*curlj(ixo^s,ndir)
949 w(ixo^s,
mag(1:ndir)) = w(ixo^s,
mag(1:ndir))-qdt*curlj(ixo^s,1:ndir)
960 integer,
intent(in) :: ixI^L, ixO^L
961 double precision,
intent(in) :: qdt
962 double precision,
intent(in) :: wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
963 double precision,
intent(inout) :: w(ixI^S,1:nw)
965 double precision :: current(ixI^S,7-2*ndir:3)
966 double precision :: tmpvec(ixI^S,1:3),tmpvec2(ixI^S,1:3),tmp(ixI^S),ehyper(ixI^S,1:3)
967 integer :: ixA^L,idir,jdir,kdir,idirmin,idirmin1
970 if (iximin^
d>ixamin^
d.or.iximax^
d<ixamax^
d|.or.) &
971 call mpistop(
"Error in add_source_hyperres: Non-conforming input limits")
974 tmpvec(ixa^s,1:ndir)=zero
976 tmpvec(ixa^s,jdir)=current(ixa^s,jdir)
980 call curlvector(tmpvec,ixi^l,ixa^l,tmpvec2,idirmin1,1,3)
983 tmpvec(ixa^s,1:ndir)=zero
984 call curlvector(tmpvec2,ixi^l,ixa^l,tmpvec,idirmin1,1,3)
985 ehyper(ixa^s,1:ndir) = - tmpvec(ixa^s,1:ndir)*
mf_eta_hyper
988 tmpvec2(ixa^s,1:ndir)=zero
989 call curlvector(ehyper,ixi^l,ixa^l,tmpvec2,idirmin1,1,3)
992 w(ixo^s,
mag(idir)) = w(ixo^s,
mag(idir))-tmpvec2(ixo^s,idir)*qdt
1004 integer,
intent(in) :: ixI^L, ixO^L
1005 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1006 double precision,
intent(inout) :: w(ixI^S,1:nw)
1007 double precision:: divb(ixI^S)
1008 integer :: idim,idir
1009 double precision :: gradPsi(ixI^S)
1031 call gradient(wct(ixi^s,
psi_),ixi^l,ixo^l,idim,gradpsi)
1043 integer,
intent(in) :: ixI^L, ixO^L
1044 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1045 double precision,
intent(inout) :: w(ixI^S,1:nw)
1046 double precision :: divb(ixI^S),v(ixI^S,1:ndir)
1057 w(ixo^s,
mag(idir))=w(ixo^s,
mag(idir))-qdt*v(ixo^s,idir)*divb(ixo^s)
1067 integer,
intent(in) :: ixI^L, ixO^L
1068 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1069 double precision,
intent(inout) :: w(ixI^S,1:nw)
1070 double precision :: divb(ixI^S),v(ixI^S,1:ndir)
1081 w(ixo^s,
mag(idir))=w(ixo^s,
mag(idir))-qdt*v(ixo^s,idir)*divb(ixo^s)
1091 integer,
intent(in) :: ixI^L, ixO^L
1092 double precision,
intent(in) :: qdt, wCT(ixI^S,1:nw), x(ixI^S,1:ndim)
1093 double precision,
intent(inout) :: w(ixI^S,1:nw)
1094 integer :: idim, idir, ixp^L, i^D, iside
1095 double precision :: divb(ixI^S),graddivb(ixI^S)
1096 logical,
dimension(-1:1^D&) :: leveljump
1104 if(i^d==0|.and.) cycle
1105 if(neighbor_type(i^d,
block%igrid)==2 .or. neighbor_type(i^d,
block%igrid)==4)
then
1106 leveljump(i^d)=.true.
1108 leveljump(i^d)=.false.
1117 i^dd=kr(^dd,^d)*(2*iside-3);
1118 if (leveljump(i^dd))
then
1120 ixpmin^d=ixomin^d-i^d
1122 ixpmax^d=ixomax^d-i^d
1133 select case(typegrad)
1135 call gradient(divb,ixi^l,ixp^l,idim,graddivb)
1137 call gradients(divb,ixi^l,ixp^l,idim,graddivb)
1141 if (slab_uniform)
then
1142 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff/(^d&1.0d0/dxlevel(^d)**2+)
1144 graddivb(ixp^s)=graddivb(ixp^s)*divbdiff &
1145 /(^d&1.0d0/block%ds(ixp^s,^d)**2+)
1148 w(ixp^s,
mag(idim))=w(ixp^s,
mag(idim))+graddivb(ixp^s)
1158 integer,
intent(in) :: ixi^
l, ixo^
l
1159 double precision,
intent(in) :: w(ixi^s,1:nw)
1160 double precision,
intent(inout) :: divb(ixi^s)
1161 logical,
intent(in),
optional :: fourthorder
1163 integer :: ixc^
l, idir
1168 ixc^
l=ixo^
l-
kr(idir,^
d);
1169 divb(ixo^s)=divb(ixo^s)+
block%ws(ixo^s,idir)*
block%surfaceC(ixo^s,idir)-&
1170 block%ws(ixc^s,idir)*
block%surfaceC(ixc^s,idir)
1172 divb(ixo^s)=divb(ixo^s)/
block%dvolume(ixo^s)
1189 integer,
intent(in) :: ixi^
l, ixo^
l
1190 double precision,
intent(in) :: w(ixi^s,1:nw)
1191 double precision :: divb(ixi^s), dsurface(ixi^s)
1193 double precision :: invb(ixo^s)
1194 integer :: ixa^
l,idims
1198 where(invb(ixo^s)/=0.d0)
1199 invb(ixo^s)=1.d0/invb(ixo^s)
1202 divb(ixo^s)=0.5d0*abs(divb(ixo^s))*invb(ixo^s)/sum(1.d0/
dxlevel(:))
1204 ixamin^
d=ixomin^
d-1;
1205 ixamax^
d=ixomax^
d-1;
1206 dsurface(ixo^s)= sum(
block%surfaceC(ixo^s,:),dim=
ndim+1)
1208 ixa^
l=ixo^
l-
kr(idims,^
d);
1209 dsurface(ixo^s)=dsurface(ixo^s)+
block%surfaceC(ixa^s,idims)
1211 divb(ixo^s)=abs(divb(ixo^s))*invb(ixo^s)*&
1212 block%dvolume(ixo^s)/dsurface(ixo^s)
1223 integer,
intent(in) :: ixo^
l, ixi^
l
1224 double precision,
intent(in) :: w(ixi^s,1:nw)
1225 integer,
intent(out) :: idirmin
1226 logical,
intent(in),
optional :: fourthorder
1227 integer :: idir, idirmin0
1230 double precision :: current(ixi^s,7-2*
ndir:3)
1234 if(
present(fourthorder))
then
1247 integer,
intent(in) :: ixI^L, ixO^L
1248 double precision,
intent(inout) :: dtnew
1249 double precision,
intent(in) :: dx^D
1250 double precision,
intent(in) :: w(ixI^S,1:nw)
1251 double precision,
intent(in) :: x(ixI^S,1:ndim)
1253 integer :: idirmin,idim
1254 double precision :: dxarr(ndim)
1255 double precision :: current(ixI^S,7-2*ndir:3),eta(ixI^S)
1262 else if (
mf_eta<zero)
then
1269 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/dxarr(idim)**2)))
1272 dtdiffpar/(smalldouble+maxval(eta(ixo^s)/
block%ds(ixo^s,idim)**2)))
1291 integer,
intent(in) :: ixI^L, ixO^L
1292 double precision,
intent(in) :: qdt, x(ixI^S,1:ndim)
1293 double precision,
intent(inout) :: wCT(ixI^S,1:nw), w(ixI^S,1:nw)
1296 double precision :: tmp(ixI^S)
1298 integer :: mr_,mphi_
1299 integer :: br_,bphi_
1307 call mpistop(
"angmomfix not implemented yet in MHD")
1312 w(ixo^s,bphi_)=w(ixo^s,bphi_)+qdt/x(ixo^s,1)*&
1313 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
1314 -wct(ixo^s,br_)*wct(ixo^s,mphi_))
1317 if(
mf_glm) w(ixo^s,br_)=w(ixo^s,br_)+qdt*wct(ixo^s,
psi_)/x(ixo^s,1)
1321 w(ixo^s,
mag(1))=w(ixo^s,
mag(1))+qdt/x(ixo^s,1)*2.0d0*wct(ixo^s,
psi_)
1327 tmp(ixo^s)=wct(ixo^s,
mom(1))*wct(ixo^s,
mag(2)) &
1328 -wct(ixo^s,
mom(2))*wct(ixo^s,
mag(1))
1330 tmp(ixo^s)=tmp(ixo^s) &
1331 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
1333 w(ixo^s,
mag(2))=w(ixo^s,
mag(2))+qdt*tmp(ixo^s)/x(ixo^s,1)
1340 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,
mag(3)) &
1341 -wct(ixo^s,
mom(3))*wct(ixo^s,
mag(1))) {^nooned &
1342 -(wct(ixo^s,
mom(3))*wct(ixo^s,
mag(2)) &
1343 -wct(ixo^s,
mom(2))*wct(ixo^s,
mag(3)))*dcos(x(ixo^s,2)) &
1345 w(ixo^s,
mag(3))=w(ixo^s,
mag(3))+qdt*tmp(ixo^s)/x(ixo^s,1)
1355 integer,
intent(in) :: ixi^
l, ixo^
l
1356 double precision,
intent(in) :: w(ixi^s, nw)
1357 double precision :: mge(ixo^s)
1359 mge = sum(w(ixo^s,
mag(:))**2, dim=
ndim+1)
1365 integer,
intent(in) :: ixi^
l, ixo^
l, idir
1366 double precision,
intent(in) :: w(ixi^s, nw)
1367 double precision :: mgf(ixo^s)
1369 mgf = w(ixo^s,
mag(idir))
1375 integer,
intent(in) :: ixi^l, ixo^l
1376 double precision,
intent(in) :: w(ixi^s, nw)
1377 double precision :: mge(ixo^s)
1379 mge = 0.5d0 * sum(w(ixo^s,
mag(:))**2, dim=
ndim+1)
1385 integer,
intent(in) :: ixI^L, ixO^L, idir
1386 double precision,
intent(in) :: qt
1387 double precision,
intent(inout) :: wLC(ixI^S,1:nw), wRC(ixI^S,1:nw)
1388 double precision,
intent(inout) :: wLp(ixI^S,1:nw), wRp(ixI^S,1:nw)
1390 double precision :: dB(ixI^S), dPsi(ixI^S)
1398 db(ixo^s) = wrp(ixo^s,
mag(idir)) - wlp(ixo^s,
mag(idir))
1399 dpsi(ixo^s) = wrp(ixo^s,
psi_) - wlp(ixo^s,
psi_)
1401 wlp(ixo^s,
mag(idir)) = 0.5d0 * (wrp(ixo^s,
mag(idir)) + wlp(ixo^s,
mag(idir))) &
1403 wlp(ixo^s,
psi_) = 0.5d0 * (wrp(ixo^s,
psi_) + wlp(ixo^s,
psi_)) &
1406 wrp(ixo^s,
mag(idir)) = wlp(ixo^s,
mag(idir))
1413 integer,
intent(in) :: igrid
1414 type(state),
target :: psb(max_blocks)
1416 integer :: iB, idims, iside, ixO^L, i^D
1425 i^d=
kr(^d,idims)*(2*iside-3);
1426 if (neighbor_type(i^d,igrid)/=1) cycle
1427 ib=(idims-1)*2+iside
1455 integer,
intent(in) :: ixG^L,ixO^L,iB
1456 double precision,
intent(inout) :: w(ixG^S,1:nw)
1457 double precision,
intent(in) :: x(ixG^S,1:ndim)
1459 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
1460 integer :: ix^D,ixF^L
1472 do ix1=ixfmax1,ixfmin1,-1
1473 w(ix1-1,ixfmin2:ixfmax2,
mag(1))=w(ix1+1,ixfmin2:ixfmax2,
mag(1)) &
1474 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,
mag(2))-&
1475 w(ix1,ixfmin2-1:ixfmax2-1,
mag(2)))
1478 do ix1=ixfmax1,ixfmin1,-1
1479 w(ix1-1,ixfmin2:ixfmax2,
mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,
mag(1))+&
1480 w(ix1,ixfmin2:ixfmax2,
mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
1481 +(w(ix1,ixfmin2+1:ixfmax2+1,
mag(2))+w(ix1,ixfmin2:ixfmax2,
mag(2)))*&
1482 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
1483 -(w(ix1,ixfmin2:ixfmax2,
mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,
mag(2)))*&
1484 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
1485 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,
mag(1))
1499 do ix1=ixfmax1,ixfmin1,-1
1500 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))=&
1501 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1)) &
1502 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,
mag(2))-&
1503 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,
mag(2))) &
1504 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,
mag(3))-&
1505 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,
mag(3)))
1508 do ix1=ixfmax1,ixfmin1,-1
1509 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))=&
1510 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))+&
1511 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1)))*&
1512 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
1513 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,
mag(2))+&
1514 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(2)))*&
1515 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
1516 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(2))+&
1517 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,
mag(2)))*&
1518 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
1519 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,
mag(3))+&
1520 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(3)))*&
1521 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
1522 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(3))+&
1523 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,
mag(3)))*&
1524 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
1525 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
1526 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))
1538 do ix1=ixfmin1,ixfmax1
1539 w(ix1+1,ixfmin2:ixfmax2,
mag(1))=w(ix1-1,ixfmin2:ixfmax2,
mag(1)) &
1540 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,
mag(2))-&
1541 w(ix1,ixfmin2-1:ixfmax2-1,
mag(2)))
1544 do ix1=ixfmin1,ixfmax1
1545 w(ix1+1,ixfmin2:ixfmax2,
mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,
mag(1))+&
1546 w(ix1,ixfmin2:ixfmax2,
mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
1547 -(w(ix1,ixfmin2+1:ixfmax2+1,
mag(2))+w(ix1,ixfmin2:ixfmax2,
mag(2)))*&
1548 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
1549 +(w(ix1,ixfmin2:ixfmax2,
mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,
mag(2)))*&
1550 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
1551 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,
mag(1))
1565 do ix1=ixfmin1,ixfmax1
1566 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))=&
1567 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1)) &
1568 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,
mag(2))-&
1569 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,
mag(2))) &
1570 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,
mag(3))-&
1571 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,
mag(3)))
1574 do ix1=ixfmin1,ixfmax1
1575 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))=&
1576 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))+&
1577 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1)))*&
1578 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
1579 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,
mag(2))+&
1580 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(2)))*&
1581 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
1582 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(2))+&
1583 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,
mag(2)))*&
1584 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
1585 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,
mag(3))+&
1586 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(3)))*&
1587 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
1588 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(3))+&
1589 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,
mag(3)))*&
1590 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
1591 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
1592 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,
mag(1))
1604 do ix2=ixfmax2,ixfmin2,-1
1605 w(ixfmin1:ixfmax1,ix2-1,
mag(2))=w(ixfmin1:ixfmax1,ix2+1,
mag(2)) &
1606 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,
mag(1))-&
1607 w(ixfmin1-1:ixfmax1-1,ix2,
mag(1)))
1610 do ix2=ixfmax2,ixfmin2,-1
1611 w(ixfmin1:ixfmax1,ix2-1,
mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,
mag(2))+&
1612 w(ixfmin1:ixfmax1,ix2,
mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
1613 +(w(ixfmin1+1:ixfmax1+1,ix2,
mag(1))+w(ixfmin1:ixfmax1,ix2,
mag(1)))*&
1614 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
1615 -(w(ixfmin1:ixfmax1,ix2,
mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,
mag(1)))*&
1616 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
1617 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,
mag(2))
1631 do ix2=ixfmax2,ixfmin2,-1
1632 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,
mag(2))=w(ixfmin1:ixfmax1,&
1633 ix2+1,ixfmin3:ixfmax3,
mag(2)) &
1634 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,
mag(1))-&
1635 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,
mag(1))) &
1636 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,
mag(3))-&
1637 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,
mag(3)))
1640 do ix2=ixfmax2,ixfmin2,-1
1641 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,
mag(2))=&
1642 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,
mag(2))+&
1643 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(2)))*&
1644 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
1645 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,
mag(1))+&
1646 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(1)))*&
1647 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
1648 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(1))+&
1649 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,
mag(1)))*&
1650 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
1651 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,
mag(3))+&
1652 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(3)))*&
1653 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
1654 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(3))+&
1655 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,
mag(3)))*&
1656 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
1657 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
1658 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(2))
1670 do ix2=ixfmin2,ixfmax2
1671 w(ixfmin1:ixfmax1,ix2+1,
mag(2))=w(ixfmin1:ixfmax1,ix2-1,
mag(2)) &
1672 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,
mag(1))-&
1673 w(ixfmin1-1:ixfmax1-1,ix2,
mag(1)))
1676 do ix2=ixfmin2,ixfmax2
1677 w(ixfmin1:ixfmax1,ix2+1,
mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,
mag(2))+&
1678 w(ixfmin1:ixfmax1,ix2,
mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
1679 -(w(ixfmin1+1:ixfmax1+1,ix2,
mag(1))+w(ixfmin1:ixfmax1,ix2,
mag(1)))*&
1680 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
1681 +(w(ixfmin1:ixfmax1,ix2,
mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,
mag(1)))*&
1682 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
1683 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,
mag(2))
1697 do ix2=ixfmin2,ixfmax2
1698 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,
mag(2))=w(ixfmin1:ixfmax1,&
1699 ix2-1,ixfmin3:ixfmax3,
mag(2)) &
1700 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,
mag(1))-&
1701 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,
mag(1))) &
1702 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,
mag(3))-&
1703 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,
mag(3)))
1706 do ix2=ixfmin2,ixfmax2
1707 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,
mag(2))=&
1708 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,
mag(2))+&
1709 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(2)))*&
1710 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
1711 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,
mag(1))+&
1712 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(1)))*&
1713 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
1714 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(1))+&
1715 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,
mag(1)))*&
1716 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
1717 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,
mag(3))+&
1718 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(3)))*&
1719 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
1720 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(3))+&
1721 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,
mag(3)))*&
1722 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
1723 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
1724 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,
mag(2))
1739 do ix3=ixfmax3,ixfmin3,-1
1740 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,
mag(3))=w(ixfmin1:ixfmax1,&
1741 ixfmin2:ixfmax2,ix3+1,
mag(3)) &
1742 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,
mag(1))-&
1743 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,
mag(1))) &
1744 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,
mag(2))-&
1745 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,
mag(2)))
1748 do ix3=ixfmax3,ixfmin3,-1
1749 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,
mag(3))=&
1750 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,
mag(3))+&
1751 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(3)))*&
1752 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
1753 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,
mag(1))+&
1754 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(1)))*&
1755 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
1756 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(1))+&
1757 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,
mag(1)))*&
1758 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
1759 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,
mag(2))+&
1760 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(2)))*&
1761 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
1762 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(2))+&
1763 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,
mag(2)))*&
1764 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
1765 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
1766 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(3))
1779 do ix3=ixfmin3,ixfmax3
1780 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,
mag(3))=w(ixfmin1:ixfmax1,&
1781 ixfmin2:ixfmax2,ix3-1,
mag(3)) &
1782 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,
mag(1))-&
1783 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,
mag(1))) &
1784 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,
mag(2))-&
1785 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,
mag(2)))
1788 do ix3=ixfmin3,ixfmax3
1789 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,
mag(3))=&
1790 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,
mag(3))+&
1791 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(3)))*&
1792 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
1793 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,
mag(1))+&
1794 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(1)))*&
1795 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
1796 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(1))+&
1797 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,
mag(1)))*&
1798 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
1799 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,
mag(2))+&
1800 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(2)))*&
1801 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
1802 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(2))+&
1803 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,
mag(2)))*&
1804 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
1805 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
1806 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,
mag(3))
1811 call mpistop(
"Special boundary is not defined for this region")
1823 double precision,
intent(in) :: qdt
1824 double precision,
intent(in) :: qt
1825 logical,
intent(inout) :: active
1826 integer :: iigrid, igrid, id
1827 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
1829 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
1830 double precision :: res
1831 double precision,
parameter :: max_residual = 1
d-3
1832 double precision,
parameter :: residual_reduction = 1
d-10
1833 integer,
parameter :: max_its = 50
1834 double precision :: residual_it(max_its), max_divb
1836 mg%operator_type = mg_laplacian
1844 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1845 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1848 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
1849 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1851 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1852 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1855 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
1856 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1860 write(*,*)
"mf_clean_divb_multigrid warning: unknown boundary type"
1861 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1862 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1870 do iigrid = 1, igridstail
1871 igrid = igrids(iigrid);
1874 lvl =
mg%boxes(id)%lvl
1875 nc =
mg%box_size_lvl(lvl)
1883 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
1884 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
1889 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
1892 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
1893 if (
mype == 0) print *,
"iteration vs residual"
1896 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
1897 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
1898 if (residual_it(n) < residual_reduction * max_divb)
exit
1900 if (
mype == 0 .and. n > max_its)
then
1901 print *,
"divb_multigrid warning: not fully converged"
1902 print *,
"current amplitude of divb: ", residual_it(max_its)
1903 print *,
"multigrid smallest grid: ", &
1904 mg%domain_size_lvl(:,
mg%lowest_lvl)
1905 print *,
"note: smallest grid ideally has <= 8 cells"
1906 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
1907 print *,
"note: dx/dy/dz should be similar"
1911 call mg_fas_vcycle(
mg, max_res=res)
1912 if (res < max_residual)
exit
1914 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
1919 do iigrid = 1, igridstail
1920 igrid = igrids(iigrid);
1929 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
1933 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
1935 call gradientx(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim),.false.)
1936 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
1958 integer,
intent(in) :: ixI^L, ixO^L
1959 double precision,
intent(in) :: qt, qdt
1961 double precision,
intent(in) :: wprim(ixI^S,1:nw)
1962 type(state) :: sCT, s
1963 type(ct_velocity) :: vcts
1964 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
1965 double precision,
intent(inout) :: fE(ixI^S,7-2*ndim:3)
1975 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
1985 integer,
intent(in) :: ixI^L, ixO^L
1986 double precision,
intent(in) :: qt, qdt
1987 type(state) :: sCT, s
1988 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
1989 double precision,
intent(inout) :: fE(ixI^S,7-2*ndim:3)
1991 integer :: hxC^L,ixC^L,jxC^L,ixCm^L
1992 integer :: idim1,idim2,idir,iwdim1,iwdim2
1993 double precision :: circ(ixI^S,1:ndim)
1995 double precision :: jce(ixI^S,7-2*ndim:3)
1997 associate(bfaces=>s%ws,x=>s%x)
2012 if (
lvc(idim1,idim2,idir)==1)
then
2014 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
2016 jxc^l=ixc^l+
kr(idim1,^
d);
2017 hxc^l=ixc^l+
kr(idim2,^
d);
2019 fe(ixc^s,idir)=quarter*(fc(ixc^s,iwdim1,idim2)+fc(jxc^s,iwdim1,idim2)&
2020 -fc(ixc^s,iwdim2,idim1)-fc(hxc^s,iwdim2,idim1))
2023 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2027 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
2038 circ(ixi^s,1:ndim)=zero
2044 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2048 if(
lvc(idim1,idim2,idir)/=0)
then
2049 hxc^l=ixc^l-
kr(idim2,^
d);
2051 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2052 +
lvc(idim1,idim2,idir)&
2059 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2061 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2073 integer,
intent(in) :: ixI^L, ixO^L
2074 double precision,
intent(in) :: qt, qdt
2076 double precision,
intent(in) :: wp(ixI^S,1:nw)
2077 type(state) :: sCT, s
2078 type(ct_velocity) :: vcts
2079 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
2080 double precision,
intent(inout) :: fE(ixI^S,7-2*ndim:3)
2082 double precision :: circ(ixI^S,1:ndim)
2084 double precision :: ECC(ixI^S,7-2*ndim:3)
2086 double precision :: EL(ixI^S),ER(ixI^S)
2088 double precision :: ELC(ixI^S),ERC(ixI^S)
2090 double precision :: jce(ixI^S,7-2*ndim:3)
2091 integer :: hxC^L,ixC^L,jxC^L,ixA^L,ixB^L
2092 integer :: idim1,idim2,idir,iwdim1,iwdim2
2094 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm)
2098 do idim1=1,ndim;
do idim2=1,ndim;
do idir=7-2*ndim,3
2099 if(
lvc(idim1,idim2,idir)==1)
then
2100 ecc(ixi^s,idir)=ecc(ixi^s,idir)+wp(ixi^s,
mag(idim1))*wp(ixi^s,
mom(idim2))
2101 else if(
lvc(idim1,idim2,idir)==-1)
then
2102 ecc(ixi^s,idir)=ecc(ixi^s,idir)-wp(ixi^s,
mag(idim1))*wp(ixi^s,
mom(idim2))
2119 if (
lvc(idim1,idim2,idir)==1)
then
2121 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
2123 jxc^l=ixc^l+
kr(idim1,^
d);
2124 hxc^l=ixc^l+
kr(idim2,^
d);
2126 fe(ixc^s,idir)=quarter*&
2127 (fc(ixc^s,iwdim1,idim2)+fc(jxc^s,iwdim1,idim2)&
2128 -fc(ixc^s,iwdim2,idim1)-fc(hxc^s,iwdim2,idim1))
2132 ixamax^
d=ixcmax^
d+
kr(idim1,^
d);
2133 el(ixa^s)=fc(ixa^s,iwdim1,idim2)-ecc(ixa^s,idir)
2134 hxc^l=ixa^l+
kr(idim2,^
d);
2135 er(ixa^s)=fc(ixa^s,iwdim1,idim2)-ecc(hxc^s,idir)
2136 where(vnorm(ixc^s,idim1)>0.d0)
2137 elc(ixc^s)=el(ixc^s)
2138 else where(vnorm(ixc^s,idim1)<0.d0)
2139 elc(ixc^s)=el(jxc^s)
2141 elc(ixc^s)=0.5d0*(el(ixc^s)+el(jxc^s))
2143 hxc^l=ixc^l+
kr(idim2,^
d);
2144 where(vnorm(hxc^s,idim1)>0.d0)
2145 erc(ixc^s)=er(ixc^s)
2146 else where(vnorm(hxc^s,idim1)<0.d0)
2147 erc(ixc^s)=er(jxc^s)
2149 erc(ixc^s)=0.5d0*(er(ixc^s)+er(jxc^s))
2151 fe(ixc^s,idir)=fe(ixc^s,idir)+0.25d0*(elc(ixc^s)+erc(ixc^s))
2154 jxc^l=ixc^l+
kr(idim2,^
d);
2156 ixamax^
d=ixcmax^
d+
kr(idim2,^
d);
2157 el(ixa^s)=-fc(ixa^s,iwdim2,idim1)-ecc(ixa^s,idir)
2158 hxc^l=ixa^l+
kr(idim1,^
d);
2159 er(ixa^s)=-fc(ixa^s,iwdim2,idim1)-ecc(hxc^s,idir)
2160 where(vnorm(ixc^s,idim2)>0.d0)
2161 elc(ixc^s)=el(ixc^s)
2162 else where(vnorm(ixc^s,idim2)<0.d0)
2163 elc(ixc^s)=el(jxc^s)
2165 elc(ixc^s)=0.5d0*(el(ixc^s)+el(jxc^s))
2167 hxc^l=ixc^l+
kr(idim1,^
d);
2168 where(vnorm(hxc^s,idim2)>0.d0)
2169 erc(ixc^s)=er(ixc^s)
2170 else where(vnorm(hxc^s,idim2)<0.d0)
2171 erc(ixc^s)=er(jxc^s)
2173 erc(ixc^s)=0.5d0*(er(ixc^s)+er(jxc^s))
2175 fe(ixc^s,idir)=fe(ixc^s,idir)+0.25d0*(elc(ixc^s)+erc(ixc^s))
2178 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2182 fe(ixc^s,idir)=fe(ixc^s,idir)*qdt*s%dsC(ixc^s,idir)
2197 circ(ixi^s,1:ndim)=zero
2202 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2206 if(
lvc(idim1,idim2,idir)/=0)
then
2207 hxc^l=ixc^l-
kr(idim2,^
d);
2209 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2210 +
lvc(idim1,idim2,idir)&
2217 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
2218 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2220 circ(ixc^s,idim1)=zero
2223 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2236 integer,
intent(in) :: ixI^L, ixO^L
2237 double precision,
intent(in) :: qt, qdt
2238 double precision,
intent(inout) :: fE(ixI^S,7-2*ndim:3)
2239 type(state) :: sCT, s
2240 type(ct_velocity) :: vcts
2242 double precision :: vtilL(ixI^S,2)
2243 double precision :: vtilR(ixI^S,2)
2244 double precision :: btilL(ixI^S,ndim)
2245 double precision :: btilR(ixI^S,ndim)
2246 double precision :: cp(ixI^S,2)
2247 double precision :: cm(ixI^S,2)
2248 double precision :: circ(ixI^S,1:ndim)
2250 double precision :: jce(ixI^S,7-2*ndim:3)
2251 integer :: hxC^L,ixC^L,ixCp^L,jxC^L,ixCm^L
2252 integer :: idim1,idim2,idir
2254 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
2255 cbarmax=>vcts%cbarmax)
2281 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
2285 idim2=mod(idir+1,3)+1
2287 jxc^l=ixc^l+
kr(idim1,^
d);
2288 ixcp^l=ixc^l+
kr(idim2,^
d);
2291 call reconstruct(ixi^l,ixc^l,idim2,vbarc(ixi^s,idim1,1),&
2292 vtill(ixi^s,2),vtilr(ixi^s,2))
2294 call reconstruct(ixi^l,ixc^l,idim1,vbarc(ixi^s,idim2,2),&
2295 vtill(ixi^s,1),vtilr(ixi^s,1))
2300 call reconstruct(ixi^l,ixc^l,idim2,bfacesct(ixi^s,idim1),&
2301 btill(ixi^s,idim1),btilr(ixi^s,idim1))
2303 call reconstruct(ixi^l,ixc^l,idim1,bfacesct(ixi^s,idim2),&
2304 btill(ixi^s,idim2),btilr(ixi^s,idim2))
2308 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
2309 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
2311 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
2312 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
2316 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
2317 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
2318 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
2319 /(cp(ixc^s,1)+cm(ixc^s,1)) &
2320 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
2321 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
2322 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
2323 /(cp(ixc^s,2)+cm(ixc^s,2))
2326 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2330 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
2344 circ(ixi^s,1:ndim)=zero
2350 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2354 if(
lvc(idim1,idim2,idir)/=0)
then
2355 hxc^l=ixc^l-
kr(idim2,^
d);
2357 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2358 +
lvc(idim1,idim2,idir)&
2365 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
2366 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2368 circ(ixc^s,idim1)=zero
2371 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2383 integer,
intent(in) :: ixI^L, ixO^L
2384 type(state),
intent(in) :: sCT, s
2386 double precision :: jce(ixI^S,7-2*ndim:3)
2389 double precision :: jcc(ixI^S,7-2*ndir:3)
2391 double precision :: xs(ixGs^T,1:ndim)
2393 double precision :: eta(ixI^S)
2394 double precision :: gradi(ixGs^T)
2395 integer :: ix^D,ixC^L,ixA^L,ixB^L,idir,idirmin,idim1,idim2
2397 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
2403 if (
lvc(idim1,idim2,idir)==0) cycle
2404 ixcmax^d=ixomax^d+1;
2405 ixcmin^d=ixomin^d+
kr(idir,^d)-2;
2406 ixbmax^d=ixcmax^d-
kr(idir,^d)+1;
2409 xs(ixb^s,:)=x(ixb^s,:)
2410 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
2411 call gradientx(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^l,idim1,gradi,.false.)
2412 if (
lvc(idim1,idim2,idir)==1)
then
2413 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
2415 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
2422 jce(ixi^s,:)=jce(ixi^s,:)*
mf_eta
2430 ixcmin^d=ixomin^d+
kr(idir,^d)-1;
2431 jcc(ixc^s,idir)=0.d0
2433 if({ ix^d==1 .and. ^d==idir | .or.}) cycle
2434 ixamin^d=ixcmin^d+ix^d;
2435 ixamax^d=ixcmax^d+ix^d;
2436 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
2438 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
2439 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
2450 integer,
intent(in) :: ixo^
l
2453 integer :: fxo^
l, gxo^
l, hxo^
l, jxo^
l, kxo^
l, idim
2455 associate(w=>s%w, ws=>s%ws)
2462 hxo^
l=ixo^
l-
kr(idim,^
d);
2465 w(ixo^s,
mag(idim))=half/s%surface(ixo^s,idim)*&
2466 (ws(ixo^s,idim)*s%surfaceC(ixo^s,idim)&
2467 +ws(hxo^s,idim)*s%surfaceC(hxo^s,idim))
2511 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
2512 double precision,
intent(inout) :: ws(ixis^s,1:nws)
2513 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2515 double precision :: adummy(ixis^s,1:3)
2524 double precision :: sum_jbb_ipe, sum_j_ipe, sum_l_ipe, f_i_ipe, volume_pe
2525 double precision :: sum_jbb, sum_j, sum_l, f_i, volume, cw_sin_theta
2526 integer :: iigrid, igrid, ix^
d
2527 integer :: amode, istatus(mpi_status_size)
2528 integer,
save :: fhmf
2529 character(len=800) :: filename,filehead
2530 character(len=800) :: line,datastr
2531 logical :: patchwi(ixg^t)
2532 logical,
save :: logmfopened=.false.
2539 do iigrid=1,igridstail; igrid=igrids(iigrid);
2544 ps(igrid)%x,1,patchwi)
2546 ps(igrid)%x,2,patchwi)
2548 ps(igrid)%x,3,patchwi)
2550 ps(igrid)%x,4,patchwi)
2552 call mpi_reduce(sum_jbb_ipe,sum_jbb,1,mpi_double_precision,&
2554 call mpi_reduce(sum_j_ipe,sum_j,1,mpi_double_precision,mpi_sum,0,&
2556 call mpi_reduce(f_i_ipe,f_i,1,mpi_double_precision,mpi_sum,0,&
2558 call mpi_reduce(sum_l_ipe,sum_l,1,mpi_double_precision,mpi_sum,0,&
2560 call mpi_reduce(volume_pe,volume,1,mpi_double_precision,mpi_sum,0,&
2566 cw_sin_theta = sum_jbb/sum_j
2572 if(.not.logmfopened)
then
2574 write(filename,
"(a,a)") trim(
base_filename),
"_mf_metrics.csv"
2578 open(unit=20,file=trim(filename),status=
'replace')
2579 close(20, status=
'delete')
2582 amode=ior(mpi_mode_create,mpi_mode_wronly)
2583 amode=ior(amode,mpi_mode_append)
2584 call mpi_file_open(mpi_comm_self,filename,amode,mpi_info_null,fhmf,
ierrmpi)
2586 filehead=
" it,time,CW_sin_theta,current,Lorenz_force,f_i"
2588 call mpi_file_write(fhmf,filehead,len_trim(filehead), &
2589 mpi_character,istatus,
ierrmpi)
2590 call mpi_file_write(fhmf,achar(10),1,mpi_character,istatus,
ierrmpi)
2594 write(datastr,
'(i6,a)')
it,
','
2595 line=trim(line)//trim(datastr)
2597 line=trim(line)//trim(datastr)
2598 write(datastr,
'(es13.6,a)') cw_sin_theta,
','
2599 line=trim(line)//trim(datastr)
2600 write(datastr,
'(es13.6,a)') sum_j,
','
2601 line=trim(line)//trim(datastr)
2602 write(datastr,
'(es13.6,a)') sum_l,
','
2603 line=trim(line)//trim(datastr)
2604 write(datastr,
'(es13.6)') f_i
2605 line=trim(line)//trim(datastr)//new_line(
'A')
2606 call mpi_file_write(fhmf,line,len_trim(line),mpi_character,istatus,
ierrmpi)
2608 call mpi_file_close(fhmf,
ierrmpi)
2618 integer,
intent(in) :: ixI^L,ixO^L
2619 double precision,
intent(in):: w(ixI^S,nw),x(ixI^S,1:ndim)
2620 double precision,
intent(inout) :: volume_pe
2621 logical,
intent(out) :: patchwi(ixI^S)
2623 double precision :: xO^L
2626 {xomin^d = xprobmin^d + 0.05d0*(xprobmax^d-xprobmin^d)\}
2627 {xomax^d = xprobmax^d - 0.05d0*(xprobmax^d-xprobmin^d)\}
2629 xomin^nd = xprobmin^nd
2634 {
do ix^db=ixomin^db,ixomax^db\}
2635 if({ x(ix^dd,^d) > xomin^d .and. x(ix^dd,^d) < xomax^d | .and. })
then
2636 patchwi(ix^d)=.true.
2637 volume_pe=volume_pe+
block%dvolume(ix^d)
2639 patchwi(ix^d)=.false.
2648 integer,
intent(in) :: ixi^
l,ixo^
l,iw
2649 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2650 double precision :: w(ixi^s,nw+
nwauxio)
2651 logical,
intent(in) :: patchwi(ixi^s)
2653 double precision,
dimension(ixI^S,7-2*ndir:3) :: current
2654 double precision,
dimension(ixI^S,1:ndir) :: bvec,qvec
2656 integer :: ix^
d,idirmin0,idirmin,idir,jdir,kdir
2662 bvec(ixo^s,:)=w(ixo^s,
mag(:))
2665 qvec(ixo^s,1:
ndir)=zero
2666 do idir=1,
ndir;
do jdir=idirmin,3;
do kdir=1,
ndir
2667 if(
lvc(idir,jdir,kdir)/=0)
then
2668 if(
lvc(idir,jdir,kdir)==1)
then
2669 qvec(ixo^s,idir)=qvec(ixo^s,idir)+current(ixo^s,jdir)*bvec(ixo^s,kdir)
2671 qvec(ixo^s,idir)=qvec(ixo^s,idir)-current(ixo^s,jdir)*bvec(ixo^s,kdir)
2674 end do;
end do;
end do
2676 {
do ix^db=ixomin^db,ixomax^db\}
2677 if(patchwi(ix^d))
then
2678 bm2=sum(bvec(ix^d,:)**2)
2679 if(bm2/=0.d0) bm2=1.d0/bm2
2681 bm2)*block%dvolume(ix^d)
2687 {
do ix^db=ixomin^db,ixomax^db\}
2695 {
do ix^db=ixomin^db,ixomax^db\}
2700 bvec(ixo^s,:)=w(ixo^s,
mag(:))
2703 qvec(ixo^s,1:ndir)=zero
2704 do idir=1,ndir;
do jdir=idirmin,3;
do kdir=1,ndir
2705 if(lvc(idir,jdir,kdir)/=0)
then
2706 if(lvc(idir,jdir,kdir)==1)
then
2707 qvec(ixo^s,idir)=qvec(ixo^s,idir)+current(ixo^s,jdir)*bvec(ixo^s,kdir)
2709 qvec(ixo^s,idir)=qvec(ixo^s,idir)-current(ixo^s,jdir)*bvec(ixo^s,kdir)
2712 end do;
end do;
end do
2714 {
do ix^db=ixomin^db,ixomax^db\}
2716 sqrt(sum(qvec(ix^d,:)**2))*block%dvolume(ix^d)
subroutine 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.
Module with geometry-related routines (e.g., divergence, curl)
subroutine divvectors(qvec, ixIL, ixOL, divq)
Calculate divergence of a vector qvec within ixL using limited extrapolation to cell edges.
integer, parameter spherical
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 divvector(qvec, ixIL, ixOL, divq, fourthorder, sixthorder)
Calculate divergence of a vector qvec within ixL.
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.
integer nstep
How many sub-steps the time integrator takes.
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 istep
Index of the sub-step in a multi-step time integrator.
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.
logical angmomfix
Enable to strictly conserve the angular momentum (works both in cylindrical and spherical coordinates...
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.
character(len=std_len) typediv
integer, dimension(:), allocatable, parameter d
integer ndir
Number of spatial dimensions (components) for vector variables.
integer ixm
the mesh range (within a block with 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 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 mf_add_source_geom(qdt, ixIL, ixOL, wCT, w, x)
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)
integer, dimension(:), allocatable, public, protected mag
Indices of the magnetic field.
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_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
subroutine mf_add_source(qdt, ixIL, ixOL, wCT, w, x, qsourcesplit, active, wCTprim)
w[iws]=w[iws]+qdt*S[iws,wCT] where S is the source based on wCT within ixO
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 get_divb(w, ixIL, ixOL, divb, fourthorder)
Calculate div B within ixO.
subroutine, public mf_to_conserved(ixIL, ixOL, w, x)
Transform primitive variables into conservative ones.
subroutine mf_angmomfix(fC, x, wnew, ixIL, ixOL, idim)
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
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_angmomfix), pointer phys_angmomfix
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.