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), w(ixI^S,1:nw)
1228 double precision :: tmp(ixI^S)
1230 integer :: mr_,mphi_
1231 integer :: br_,bphi_
1234 br_=mag(1); bphi_=mag(1)-1+
phi_
1241 w(ixo^s,bphi_)=w(ixo^s,bphi_)+qdt/x(ixo^s,1)*&
1242 (wct(ixo^s,bphi_)*wct(ixo^s,mr_) &
1243 -wct(ixo^s,br_)*wct(ixo^s,mphi_))
1246 if(
mf_glm) w(ixo^s,br_)=w(ixo^s,br_)+qdt*wct(ixo^s,
psi_)/x(ixo^s,1)
1250 w(ixo^s,mag(1))=w(ixo^s,mag(1))+qdt/x(ixo^s,1)*2.0d0*wct(ixo^s,
psi_)
1256 tmp(ixo^s)=wct(ixo^s,
mom(1))*wct(ixo^s,mag(2)) &
1257 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(1))
1259 tmp(ixo^s)=tmp(ixo^s) &
1260 + dcos(x(ixo^s,2))/dsin(x(ixo^s,2))*wct(ixo^s,
psi_)
1262 w(ixo^s,mag(2))=w(ixo^s,mag(2))+qdt*tmp(ixo^s)/x(ixo^s,1)
1269 tmp(ixo^s)=(wct(ixo^s,
mom(1))*wct(ixo^s,mag(3)) &
1270 -wct(ixo^s,
mom(3))*wct(ixo^s,mag(1))) {^nooned &
1271 -(wct(ixo^s,
mom(3))*wct(ixo^s,mag(2)) &
1272 -wct(ixo^s,
mom(2))*wct(ixo^s,mag(3)))*dcos(x(ixo^s,2)) &
1274 w(ixo^s,mag(3))=w(ixo^s,mag(3))+qdt*tmp(ixo^s)/x(ixo^s,1)
1284 integer,
intent(in) :: ixi^
l, ixo^
l
1285 double precision,
intent(in) :: w(ixi^s, nw)
1286 double precision :: mge(ixo^s)
1288 mge = sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
1294 integer,
intent(in) :: ixi^
l, ixo^
l, idir
1295 double precision,
intent(in) :: w(ixi^s, nw)
1296 double precision :: mgf(ixo^s)
1298 mgf = w(ixo^s, mag(idir))
1304 integer,
intent(in) :: ixi^l, ixo^l
1305 double precision,
intent(in) :: w(ixi^s, nw)
1306 double precision :: mge(ixo^s)
1308 mge = 0.5d0 * sum(w(ixo^s, mag(:))**2, dim=
ndim+1)
1314 integer,
intent(in) :: ixI^L, ixO^L, idir
1315 double precision,
intent(in) :: qt
1316 double precision,
intent(inout) :: wLC(ixI^S,1:nw), wRC(ixI^S,1:nw)
1317 double precision,
intent(inout) :: wLp(ixI^S,1:nw), wRp(ixI^S,1:nw)
1319 double precision :: dB(ixI^S), dPsi(ixI^S)
1327 db(ixo^s) = wrp(ixo^s,mag(idir)) - wlp(ixo^s,mag(idir))
1328 dpsi(ixo^s) = wrp(ixo^s,
psi_) - wlp(ixo^s,
psi_)
1330 wlp(ixo^s,mag(idir)) = 0.5d0 * (wrp(ixo^s,mag(idir)) + wlp(ixo^s,mag(idir))) &
1332 wlp(ixo^s,
psi_) = 0.5d0 * (wrp(ixo^s,
psi_) + wlp(ixo^s,
psi_)) &
1335 wrp(ixo^s,mag(idir)) = wlp(ixo^s,mag(idir))
1342 integer,
intent(in) :: igrid
1343 type(state),
target :: psb(max_blocks)
1345 integer :: iB, idims, iside, ixO^L, i^D
1354 i^d=
kr(^d,idims)*(2*iside-3);
1355 if (neighbor_type(i^d,igrid)/=1) cycle
1356 ib=(idims-1)*2+iside
1384 integer,
intent(in) :: ixG^L,ixO^L,iB
1385 double precision,
intent(inout) :: w(ixG^S,1:nw)
1386 double precision,
intent(in) :: x(ixG^S,1:ndim)
1388 double precision :: dx1x2,dx1x3,dx2x1,dx2x3,dx3x1,dx3x2
1389 integer :: ix^D,ixF^L
1401 do ix1=ixfmax1,ixfmin1,-1
1402 w(ix1-1,ixfmin2:ixfmax2,mag(1))=w(ix1+1,ixfmin2:ixfmax2,mag(1)) &
1403 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
1404 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
1407 do ix1=ixfmax1,ixfmin1,-1
1408 w(ix1-1,ixfmin2:ixfmax2,mag(1))=( (w(ix1+1,ixfmin2:ixfmax2,mag(1))+&
1409 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1,ixfmin2:ixfmax2,1)&
1410 +(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
1411 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
1412 -(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
1413 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
1414 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
1428 do ix1=ixfmax1,ixfmin1,-1
1429 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1430 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
1431 +dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
1432 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
1433 +dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
1434 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
1437 do ix1=ixfmax1,ixfmin1,-1
1438 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1439 ( (w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
1440 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
1441 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
1442 +(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
1443 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
1444 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
1445 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
1446 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
1447 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
1448 +(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
1449 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
1450 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
1451 -(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
1452 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1453 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
1454 /
block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
1455 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
1467 do ix1=ixfmin1,ixfmax1
1468 w(ix1+1,ixfmin2:ixfmax2,mag(1))=w(ix1-1,ixfmin2:ixfmax2,mag(1)) &
1469 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))-&
1470 w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))
1473 do ix1=ixfmin1,ixfmax1
1474 w(ix1+1,ixfmin2:ixfmax2,mag(1))=( (w(ix1-1,ixfmin2:ixfmax2,mag(1))+&
1475 w(ix1,ixfmin2:ixfmax2,mag(1)))*
block%surfaceC(ix1-1,ixfmin2:ixfmax2,1)&
1476 -(w(ix1,ixfmin2+1:ixfmax2+1,mag(2))+w(ix1,ixfmin2:ixfmax2,mag(2)))*&
1477 block%surfaceC(ix1,ixfmin2:ixfmax2,2)&
1478 +(w(ix1,ixfmin2:ixfmax2,mag(2))+w(ix1,ixfmin2-1:ixfmax2-1,mag(2)))*&
1479 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,2) )&
1480 /
block%surfaceC(ix1,ixfmin2:ixfmax2,1)-w(ix1,ixfmin2:ixfmax2,mag(1))
1494 do ix1=ixfmin1,ixfmax1
1495 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1496 w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)) &
1497 -dx1x2*(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))-&
1498 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2))) &
1499 -dx1x3*(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))-&
1500 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))
1503 do ix1=ixfmin1,ixfmax1
1504 w(ix1+1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))=&
1505 ( (w(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))+&
1506 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1)))*&
1507 block%surfaceC(ix1-1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)&
1508 -(w(ix1,ixfmin2+1:ixfmax2+1,ixfmin3:ixfmax3,mag(2))+&
1509 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2)))*&
1510 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,2)&
1511 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(2))+&
1512 w(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,mag(2)))*&
1513 block%surfaceC(ix1,ixfmin2-1:ixfmax2-1,ixfmin3:ixfmax3,2)&
1514 -(w(ix1,ixfmin2:ixfmax2,ixfmin3+1:ixfmax3+1,mag(3))+&
1515 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3)))*&
1516 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,3)&
1517 +(w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(3))+&
1518 w(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1519 block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3-1:ixfmax3-1,3) )&
1520 /
block%surfaceC(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,1)-&
1521 w(ix1,ixfmin2:ixfmax2,ixfmin3:ixfmax3,mag(1))
1533 do ix2=ixfmax2,ixfmin2,-1
1534 w(ixfmin1:ixfmax1,ix2-1,mag(2))=w(ixfmin1:ixfmax1,ix2+1,mag(2)) &
1535 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
1536 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
1539 do ix2=ixfmax2,ixfmin2,-1
1540 w(ixfmin1:ixfmax1,ix2-1,mag(2))=( (w(ixfmin1:ixfmax1,ix2+1,mag(2))+&
1541 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2,2)&
1542 +(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
1543 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
1544 -(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
1545 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
1546 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
1560 do ix2=ixfmax2,ixfmin2,-1
1561 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
1562 ix2+1,ixfmin3:ixfmax3,mag(2)) &
1563 +dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
1564 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
1565 +dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
1566 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
1569 do ix2=ixfmax2,ixfmin2,-1
1570 w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))=&
1571 ( (w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))+&
1572 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
1573 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)&
1574 +(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
1575 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1576 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
1577 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
1578 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1579 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
1580 +(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
1581 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
1582 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
1583 -(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
1584 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1585 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
1586 /
block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)-&
1587 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
1599 do ix2=ixfmin2,ixfmax2
1600 w(ixfmin1:ixfmax1,ix2+1,mag(2))=w(ixfmin1:ixfmax1,ix2-1,mag(2)) &
1601 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))-&
1602 w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))
1605 do ix2=ixfmin2,ixfmax2
1606 w(ixfmin1:ixfmax1,ix2+1,mag(2))=( (w(ixfmin1:ixfmax1,ix2-1,mag(2))+&
1607 w(ixfmin1:ixfmax1,ix2,mag(2)))*
block%surfaceC(ixfmin1:ixfmax1,ix2-1,2)&
1608 -(w(ixfmin1+1:ixfmax1+1,ix2,mag(1))+w(ixfmin1:ixfmax1,ix2,mag(1)))*&
1609 block%surfaceC(ixfmin1:ixfmax1,ix2,1)&
1610 +(w(ixfmin1:ixfmax1,ix2,mag(1))+w(ixfmin1-1:ixfmax1-1,ix2,mag(1)))*&
1611 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,1) )&
1612 /
block%surfaceC(ixfmin1:ixfmax1,ix2,2)-w(ixfmin1:ixfmax1,ix2,mag(2))
1626 do ix2=ixfmin2,ixfmax2
1627 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=w(ixfmin1:ixfmax1,&
1628 ix2-1,ixfmin3:ixfmax3,mag(2)) &
1629 -dx2x1*(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))-&
1630 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1))) &
1631 -dx2x3*(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))-&
1632 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))
1635 do ix2=ixfmin2,ixfmax2
1636 w(ixfmin1:ixfmax1,ix2+1,ixfmin3:ixfmax3,mag(2))=&
1637 ( (w(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,mag(2))+&
1638 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2)))*&
1639 block%surfaceC(ixfmin1:ixfmax1,ix2-1,ixfmin3:ixfmax3,2)&
1640 -(w(ixfmin1+1:ixfmax1+1,ix2,ixfmin3:ixfmax3,mag(1))+&
1641 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1642 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,1)&
1643 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(1))+&
1644 w(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,mag(1)))*&
1645 block%surfaceC(ixfmin1-1:ixfmax1-1,ix2,ixfmin3:ixfmax3,1)&
1646 -(w(ixfmin1:ixfmax1,ix2,ixfmin3+1:ixfmax3+1,mag(3))+&
1647 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3)))*&
1648 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,3)&
1649 +(w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(3))+&
1650 w(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,mag(3)))*&
1651 block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3-1:ixfmax3-1,3) )&
1652 /
block%surfaceC(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,2)-&
1653 w(ixfmin1:ixfmax1,ix2,ixfmin3:ixfmax3,mag(2))
1668 do ix3=ixfmax3,ixfmin3,-1
1669 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=w(ixfmin1:ixfmax1,&
1670 ixfmin2:ixfmax2,ix3+1,mag(3)) &
1671 +dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
1672 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
1673 +dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
1674 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
1677 do ix3=ixfmax3,ixfmin3,-1
1678 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))=&
1679 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))+&
1680 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
1681 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)&
1682 +(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
1683 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1684 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
1685 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
1686 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1687 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
1688 +(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
1689 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
1690 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
1691 -(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
1692 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
1693 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
1694 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)-&
1695 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
1708 do ix3=ixfmin3,ixfmax3
1709 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=w(ixfmin1:ixfmax1,&
1710 ixfmin2:ixfmax2,ix3-1,mag(3)) &
1711 -dx3x1*(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))-&
1712 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1))) &
1713 -dx3x2*(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))-&
1714 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))
1717 do ix3=ixfmin3,ixfmax3
1718 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3+1,mag(3))=&
1719 ( (w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,mag(3))+&
1720 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3)))*&
1721 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3-1,3)&
1722 -(w(ixfmin1+1:ixfmax1+1,ixfmin2:ixfmax2,ix3,mag(1))+&
1723 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1724 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,1)&
1725 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(1))+&
1726 w(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,mag(1)))*&
1727 block%surfaceC(ixfmin1-1:ixfmax1-1,ixfmin2:ixfmax2,ix3,1)&
1728 -(w(ixfmin1:ixfmax1,ixfmin2+1:ixfmax2+1,ix3,mag(2))+&
1729 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2)))*&
1730 block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,2)&
1731 +(w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(2))+&
1732 w(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,mag(2)))*&
1733 block%surfaceC(ixfmin1:ixfmax1,ixfmin2-1:ixfmax2-1,ix3,2) )&
1734 /
block%surfaceC(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,3)-&
1735 w(ixfmin1:ixfmax1,ixfmin2:ixfmax2,ix3,mag(3))
1740 call mpistop(
"Special boundary is not defined for this region")
1752 double precision,
intent(in) :: qdt
1753 double precision,
intent(in) :: qt
1754 logical,
intent(inout) :: active
1755 integer :: iigrid, igrid, id
1756 integer :: n, nc, lvl, ix^
l, ixc^
l, idim
1758 double precision :: tmp(ixg^t), grad(ixg^t,
ndim)
1759 double precision :: res
1760 double precision,
parameter :: max_residual = 1
d-3
1761 double precision,
parameter :: residual_reduction = 1
d-10
1762 integer,
parameter :: max_its = 50
1763 double precision :: residual_it(max_its), max_divb
1765 mg%operator_type = mg_laplacian
1773 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1774 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1777 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
1778 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1780 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1781 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1784 mg%bc(n, mg_iphi)%bc_type = mg_bc_neumann
1785 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1789 write(*,*)
"mf_clean_divb_multigrid warning: unknown boundary type"
1790 mg%bc(n, mg_iphi)%bc_type = mg_bc_dirichlet
1791 mg%bc(n, mg_iphi)%bc_value = 0.0_dp
1799 do iigrid = 1, igridstail
1800 igrid = igrids(iigrid);
1803 lvl =
mg%boxes(id)%lvl
1804 nc =
mg%box_size_lvl(lvl)
1810 call get_divb(ps(igrid)%w(ixg^t, 1:nw), ixg^
ll,
ixm^
ll, tmp, &
1812 mg%boxes(id)%cc({1:nc}, mg_irhs) = tmp(
ixm^t)
1813 max_divb = max(max_divb, maxval(abs(tmp(
ixm^t))))
1818 call mpi_allreduce(mpi_in_place, max_divb, 1, mpi_double_precision, &
1821 if (
mype == 0) print *,
"Performing multigrid divB cleaning"
1822 if (
mype == 0) print *,
"iteration vs residual"
1825 call mg_fas_fmg(
mg, n>1, max_res=residual_it(n))
1826 if (
mype == 0)
write(*,
"(I4,E11.3)") n, residual_it(n)
1827 if (residual_it(n) < residual_reduction * max_divb)
exit
1829 if (
mype == 0 .and. n > max_its)
then
1830 print *,
"divb_multigrid warning: not fully converged"
1831 print *,
"current amplitude of divb: ", residual_it(max_its)
1832 print *,
"multigrid smallest grid: ", &
1833 mg%domain_size_lvl(:,
mg%lowest_lvl)
1834 print *,
"note: smallest grid ideally has <= 8 cells"
1835 print *,
"multigrid dx/dy/dz ratio: ",
mg%dr(:, 1)/
mg%dr(1, 1)
1836 print *,
"note: dx/dy/dz should be similar"
1840 call mg_fas_vcycle(
mg, max_res=res)
1841 if (res < max_residual)
exit
1843 if (res > max_residual)
call mpistop(
"divb_multigrid: no convergence")
1848 do iigrid = 1, igridstail
1849 igrid = igrids(iigrid);
1858 tmp(ix^s) =
mg%boxes(id)%cc({:,}, mg_iphi)
1862 ixcmin^
d=ixmlo^
d-
kr(idim,^
d);
1864 call gradientx(tmp,ps(igrid)%x,ixg^
ll,ixc^
l,idim,grad(ixg^t,idim),.false.)
1865 ps(igrid)%ws(ixc^s,idim)=ps(igrid)%ws(ixc^s,idim)-grad(ixc^s,idim)
1873 ps(igrid)%w(
ixm^t, mag(1:
ndim)) = &
1874 ps(igrid)%w(
ixm^t, mag(1:
ndim)) - grad(
ixm^t, :)
1887 integer,
intent(in) :: ixI^L, ixO^L
1888 double precision,
intent(in) :: qt, qdt
1890 double precision,
intent(in) :: wprim(ixI^S,1:nw)
1891 type(state) :: sCT, s
1892 type(ct_velocity) :: vcts
1893 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
1894 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
1904 call mpistop(
'choose average, uct_contact,or uct_hll for type_ct!')
1914 integer,
intent(in) :: ixI^L, ixO^L
1915 double precision,
intent(in) :: qt, qdt
1916 type(state) :: sCT, s
1917 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
1918 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
1920 integer :: hxC^L,ixC^L,jxC^L,ixCm^L
1921 integer :: idim1,idim2,idir,iwdim1,iwdim2
1922 double precision :: circ(ixI^S,1:ndim)
1924 double precision :: jce(ixI^S,sdim:3)
1926 associate(bfaces=>s%ws,x=>s%x)
1941 if (
lvc(idim1,idim2,idir)==1)
then
1943 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
1945 jxc^l=ixc^l+
kr(idim1,^
d);
1946 hxc^l=ixc^l+
kr(idim2,^
d);
1948 fe(ixc^s,idir)=quarter*(fc(ixc^s,iwdim1,idim2)+fc(jxc^s,iwdim1,idim2)&
1949 -fc(ixc^s,iwdim2,idim1)-fc(hxc^s,iwdim2,idim1))
1952 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
1956 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
1967 circ(ixi^s,1:ndim)=zero
1973 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
1977 if(
lvc(idim1,idim2,idir)/=0)
then
1978 hxc^l=ixc^l-
kr(idim2,^
d);
1980 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
1981 +
lvc(idim1,idim2,idir)&
1988 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
1990 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2002 integer,
intent(in) :: ixI^L, ixO^L
2003 double precision,
intent(in) :: qt, qdt
2005 double precision,
intent(in) :: wp(ixI^S,1:nw)
2006 type(state) :: sCT, s
2007 type(ct_velocity) :: vcts
2008 double precision,
intent(in) :: fC(ixI^S,1:nwflux,1:ndim)
2009 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
2011 double precision :: circ(ixI^S,1:ndim)
2013 double precision :: ECC(ixI^S,sdim:3)
2015 double precision :: EL(ixI^S),ER(ixI^S)
2017 double precision :: ELC(ixI^S),ERC(ixI^S)
2019 double precision :: jce(ixI^S,sdim:3)
2020 integer :: hxC^L,ixC^L,jxC^L,ixA^L,ixB^L
2021 integer :: idim1,idim2,idir,iwdim1,iwdim2
2023 associate(bfaces=>s%ws,x=>s%x,w=>s%w,vnorm=>vcts%vnorm)
2027 do idim1=1,ndim;
do idim2=1,ndim;
do idir=sdim,3
2028 if(
lvc(idim1,idim2,idir)==1)
then
2029 ecc(ixi^s,idir)=ecc(ixi^s,idir)+wp(ixi^s,mag(idim1))*wp(ixi^s,
mom(idim2))
2030 else if(
lvc(idim1,idim2,idir)==-1)
then
2031 ecc(ixi^s,idir)=ecc(ixi^s,idir)-wp(ixi^s,mag(idim1))*wp(ixi^s,
mom(idim2))
2048 if (
lvc(idim1,idim2,idir)==1)
then
2050 ixcmin^
d=ixomin^
d+
kr(idir,^
d)-1;
2052 jxc^l=ixc^l+
kr(idim1,^
d);
2053 hxc^l=ixc^l+
kr(idim2,^
d);
2055 fe(ixc^s,idir)=quarter*&
2056 (fc(ixc^s,iwdim1,idim2)+fc(jxc^s,iwdim1,idim2)&
2057 -fc(ixc^s,iwdim2,idim1)-fc(hxc^s,iwdim2,idim1))
2061 ixamax^
d=ixcmax^
d+
kr(idim1,^
d);
2062 el(ixa^s)=fc(ixa^s,iwdim1,idim2)-ecc(ixa^s,idir)
2063 hxc^l=ixa^l+
kr(idim2,^
d);
2064 er(ixa^s)=fc(ixa^s,iwdim1,idim2)-ecc(hxc^s,idir)
2065 where(vnorm(ixc^s,idim1)>0.d0)
2066 elc(ixc^s)=el(ixc^s)
2067 else where(vnorm(ixc^s,idim1)<0.d0)
2068 elc(ixc^s)=el(jxc^s)
2070 elc(ixc^s)=0.5d0*(el(ixc^s)+el(jxc^s))
2072 hxc^l=ixc^l+
kr(idim2,^
d);
2073 where(vnorm(hxc^s,idim1)>0.d0)
2074 erc(ixc^s)=er(ixc^s)
2075 else where(vnorm(hxc^s,idim1)<0.d0)
2076 erc(ixc^s)=er(jxc^s)
2078 erc(ixc^s)=0.5d0*(er(ixc^s)+er(jxc^s))
2080 fe(ixc^s,idir)=fe(ixc^s,idir)+0.25d0*(elc(ixc^s)+erc(ixc^s))
2083 jxc^l=ixc^l+
kr(idim2,^
d);
2085 ixamax^
d=ixcmax^
d+
kr(idim2,^
d);
2086 el(ixa^s)=-fc(ixa^s,iwdim2,idim1)-ecc(ixa^s,idir)
2087 hxc^l=ixa^l+
kr(idim1,^
d);
2088 er(ixa^s)=-fc(ixa^s,iwdim2,idim1)-ecc(hxc^s,idir)
2089 where(vnorm(ixc^s,idim2)>0.d0)
2090 elc(ixc^s)=el(ixc^s)
2091 else where(vnorm(ixc^s,idim2)<0.d0)
2092 elc(ixc^s)=el(jxc^s)
2094 elc(ixc^s)=0.5d0*(el(ixc^s)+el(jxc^s))
2096 hxc^l=ixc^l+
kr(idim1,^
d);
2097 where(vnorm(hxc^s,idim2)>0.d0)
2098 erc(ixc^s)=er(ixc^s)
2099 else where(vnorm(hxc^s,idim2)<0.d0)
2100 erc(ixc^s)=er(jxc^s)
2102 erc(ixc^s)=0.5d0*(er(ixc^s)+er(jxc^s))
2104 fe(ixc^s,idir)=fe(ixc^s,idir)+0.25d0*(elc(ixc^s)+erc(ixc^s))
2107 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2111 fe(ixc^s,idir)=fe(ixc^s,idir)*qdt*s%dsC(ixc^s,idir)
2126 circ(ixi^s,1:ndim)=zero
2131 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2135 if(
lvc(idim1,idim2,idir)/=0)
then
2136 hxc^l=ixc^l-
kr(idim2,^
d);
2138 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2139 +
lvc(idim1,idim2,idir)&
2146 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
2147 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2149 circ(ixc^s,idim1)=zero
2152 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2165 integer,
intent(in) :: ixI^L, ixO^L
2166 double precision,
intent(in) :: qt, qdt
2167 double precision,
intent(inout) :: fE(ixI^S,sdim:3)
2168 type(state) :: sCT, s
2169 type(ct_velocity) :: vcts
2171 double precision :: vtilL(ixI^S,2)
2172 double precision :: vtilR(ixI^S,2)
2173 double precision :: btilL(ixI^S,ndim)
2174 double precision :: btilR(ixI^S,ndim)
2175 double precision :: cp(ixI^S,2)
2176 double precision :: cm(ixI^S,2)
2177 double precision :: circ(ixI^S,1:ndim)
2179 double precision :: jce(ixI^S,sdim:3)
2180 integer :: hxC^L,ixC^L,ixCp^L,jxC^L,ixCm^L
2181 integer :: idim1,idim2,idir
2183 associate(bfaces=>s%ws,bfacesct=>sct%ws,x=>s%x,vbarc=>vcts%vbarC,cbarmin=>vcts%cbarmin,&
2184 cbarmax=>vcts%cbarmax)
2210 ixcmin^
d=ixomin^
d-1+
kr(idir,^
d);
2214 idim2=mod(idir+1,3)+1
2216 jxc^l=ixc^l+
kr(idim1,^
d);
2217 ixcp^l=ixc^l+
kr(idim2,^
d);
2220 call reconstruct(ixi^l,ixc^l,idim2,vbarc(ixi^s,idim1,1),&
2221 vtill(ixi^s,2),vtilr(ixi^s,2))
2223 call reconstruct(ixi^l,ixc^l,idim1,vbarc(ixi^s,idim2,2),&
2224 vtill(ixi^s,1),vtilr(ixi^s,1))
2229 call reconstruct(ixi^l,ixc^l,idim2,bfacesct(ixi^s,idim1),&
2230 btill(ixi^s,idim1),btilr(ixi^s,idim1))
2232 call reconstruct(ixi^l,ixc^l,idim1,bfacesct(ixi^s,idim2),&
2233 btill(ixi^s,idim2),btilr(ixi^s,idim2))
2237 cm(ixc^s,1)=max(cbarmin(ixcp^s,idim1),cbarmin(ixc^s,idim1))
2238 cp(ixc^s,1)=max(cbarmax(ixcp^s,idim1),cbarmax(ixc^s,idim1))
2240 cm(ixc^s,2)=max(cbarmin(jxc^s,idim2),cbarmin(ixc^s,idim2))
2241 cp(ixc^s,2)=max(cbarmax(jxc^s,idim2),cbarmax(ixc^s,idim2))
2245 fe(ixc^s,idir)=-(cp(ixc^s,1)*vtill(ixc^s,1)*btill(ixc^s,idim2) &
2246 + cm(ixc^s,1)*vtilr(ixc^s,1)*btilr(ixc^s,idim2) &
2247 - cp(ixc^s,1)*cm(ixc^s,1)*(btilr(ixc^s,idim2)-btill(ixc^s,idim2)))&
2248 /(cp(ixc^s,1)+cm(ixc^s,1)) &
2249 +(cp(ixc^s,2)*vtill(ixc^s,2)*btill(ixc^s,idim1) &
2250 + cm(ixc^s,2)*vtilr(ixc^s,2)*btilr(ixc^s,idim1) &
2251 - cp(ixc^s,2)*cm(ixc^s,2)*(btilr(ixc^s,idim1)-btill(ixc^s,idim1)))&
2252 /(cp(ixc^s,2)+cm(ixc^s,2))
2255 if(
mf_eta/=zero) fe(ixc^s,idir)=fe(ixc^s,idir)+jce(ixc^s,idir)
2259 fe(ixc^s,idir)=qdt*s%dsC(ixc^s,idir)*fe(ixc^s,idir)
2273 circ(ixi^s,1:ndim)=zero
2279 ixcmin^
d=ixomin^
d-
kr(idim1,^
d);
2283 if(
lvc(idim1,idim2,idir)/=0)
then
2284 hxc^l=ixc^l-
kr(idim2,^
d);
2286 circ(ixc^s,idim1)=circ(ixc^s,idim1)&
2287 +
lvc(idim1,idim2,idir)&
2294 where(s%surfaceC(ixc^s,idim1) > 1.0
d-9*s%dvolume(ixc^s))
2295 circ(ixc^s,idim1)=circ(ixc^s,idim1)/s%surfaceC(ixc^s,idim1)
2297 circ(ixc^s,idim1)=zero
2300 bfaces(ixc^s,idim1)=bfaces(ixc^s,idim1)-circ(ixc^s,idim1)
2312 integer,
intent(in) :: ixI^L, ixO^L
2313 type(state),
intent(in) :: sCT, s
2315 double precision :: jce(ixI^S,sdim:3)
2318 double precision :: jcc(ixI^S,7-2*ndir:3)
2320 double precision :: xs(ixGs^T,1:ndim)
2322 double precision :: eta(ixI^S)
2323 double precision :: gradi(ixGs^T)
2324 integer :: ix^D,ixC^L,ixA^L,ixB^L,idir,idirmin,idim1,idim2
2326 associate(x=>s%x,
dx=>s%dx,w=>s%w,wct=>sct%w,wcts=>sct%ws)
2332 if (
lvc(idim1,idim2,idir)==0) cycle
2333 ixcmax^d=ixomax^d+1;
2334 ixcmin^d=ixomin^d+
kr(idir,^d)-2;
2335 ixbmax^d=ixcmax^d-
kr(idir,^d)+1;
2338 xs(ixb^s,:)=x(ixb^s,:)
2339 xs(ixb^s,idim2)=x(ixb^s,idim2)+half*
dx(ixb^s,idim2)
2340 call gradientx(wcts(ixgs^t,idim2),xs,ixgs^
ll,ixc^l,idim1,gradi,.false.)
2341 if (
lvc(idim1,idim2,idir)==1)
then
2342 jce(ixc^s,idir)=jce(ixc^s,idir)+gradi(ixc^s)
2344 jce(ixc^s,idir)=jce(ixc^s,idir)-gradi(ixc^s)
2351 jce(ixi^s,:)=jce(ixi^s,:)*
mf_eta
2359 ixcmin^d=ixomin^d+
kr(idir,^d)-1;
2360 jcc(ixc^s,idir)=0.d0
2362 if({ ix^d==1 .and. ^d==idir | .or.}) cycle
2363 ixamin^d=ixcmin^d+ix^d;
2364 ixamax^d=ixcmax^d+ix^d;
2365 jcc(ixc^s,idir)=jcc(ixc^s,idir)+eta(ixa^s)
2367 jcc(ixc^s,idir)=jcc(ixc^s,idir)*0.25d0
2368 jce(ixc^s,idir)=jce(ixc^s,idir)*jcc(ixc^s,idir)
2379 integer,
intent(in) :: ixo^
l
2382 integer :: fxo^
l, gxo^
l, hxo^
l, jxo^
l, kxo^
l, idim
2384 associate(w=>s%w, ws=>s%ws)
2391 hxo^
l=ixo^
l-
kr(idim,^
d);
2394 w(ixo^s,mag(idim))=half/s%surface(ixo^s,idim)*&
2395 (ws(ixo^s,idim)*s%surfaceC(ixo^s,idim)&
2396 +ws(hxo^s,idim)*s%surfaceC(hxo^s,idim))
2440 integer,
intent(in) :: ixis^
l, ixi^
l, ixo^
l
2441 double precision,
intent(inout) :: ws(ixis^s,1:nws)
2442 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2444 double precision :: adummy(ixis^s,1:3)
2453 double precision :: sum_jbb_ipe, sum_j_ipe, sum_l_ipe, f_i_ipe, volume_pe
2454 double precision :: sum_jbb, sum_j, sum_l, f_i, volume, cw_sin_theta
2455 integer :: iigrid, igrid, ix^
d
2456 integer :: amode, istatus(mpi_status_size)
2457 integer,
save :: fhmf
2458 character(len=800) :: filename,filehead
2459 character(len=800) :: line,datastr
2460 logical :: patchwi(ixg^t)
2461 logical,
save :: logmfopened=.false.
2468 do iigrid=1,igridstail; igrid=igrids(iigrid);
2473 ps(igrid)%x,1,patchwi)
2475 ps(igrid)%x,2,patchwi)
2477 ps(igrid)%x,3,patchwi)
2479 ps(igrid)%x,4,patchwi)
2481 call mpi_reduce(sum_jbb_ipe,sum_jbb,1,mpi_double_precision,&
2483 call mpi_reduce(sum_j_ipe,sum_j,1,mpi_double_precision,mpi_sum,0,&
2485 call mpi_reduce(f_i_ipe,f_i,1,mpi_double_precision,mpi_sum,0,&
2487 call mpi_reduce(sum_l_ipe,sum_l,1,mpi_double_precision,mpi_sum,0,&
2489 call mpi_reduce(volume_pe,volume,1,mpi_double_precision,mpi_sum,0,&
2495 cw_sin_theta = sum_jbb/sum_j
2501 if(.not.logmfopened)
then
2503 write(filename,
"(a,a)") trim(
base_filename),
"_mf_metrics.csv"
2507 open(unit=20,file=trim(filename),status=
'replace')
2508 close(20, status=
'delete')
2511 amode=ior(mpi_mode_create,mpi_mode_wronly)
2512 amode=ior(amode,mpi_mode_append)
2513 call mpi_file_open(mpi_comm_self,filename,amode,mpi_info_null,fhmf,
ierrmpi)
2515 filehead=
" it,time,CW_sin_theta,current,Lorenz_force,f_i"
2517 call mpi_file_write(fhmf,filehead,len_trim(filehead), &
2518 mpi_character,istatus,
ierrmpi)
2519 call mpi_file_write(fhmf,achar(10),1,mpi_character,istatus,
ierrmpi)
2523 write(datastr,
'(i6,a)')
it,
','
2524 line=trim(line)//trim(datastr)
2526 line=trim(line)//trim(datastr)
2527 write(datastr,
'(es13.6,a)') cw_sin_theta,
','
2528 line=trim(line)//trim(datastr)
2529 write(datastr,
'(es13.6,a)') sum_j,
','
2530 line=trim(line)//trim(datastr)
2531 write(datastr,
'(es13.6,a)') sum_l,
','
2532 line=trim(line)//trim(datastr)
2533 write(datastr,
'(es13.6)') f_i
2534 line=trim(line)//trim(datastr)//new_line(
'A')
2535 call mpi_file_write(fhmf,line,len_trim(line),mpi_character,istatus,
ierrmpi)
2537 call mpi_file_close(fhmf,
ierrmpi)
2547 integer,
intent(in) :: ixI^L,ixO^L
2548 double precision,
intent(in):: w(ixI^S,nw),x(ixI^S,1:ndim)
2549 double precision,
intent(inout) :: volume_pe
2550 logical,
intent(out) :: patchwi(ixI^S)
2552 double precision :: xO^L
2555 {xomin^d = xprobmin^d + 0.05d0*(xprobmax^d-xprobmin^d)\}
2556 {xomax^d = xprobmax^d - 0.05d0*(xprobmax^d-xprobmin^d)\}
2558 xomin^nd = xprobmin^nd
2563 {
do ix^db=ixomin^db,ixomax^db\}
2564 if({ x(ix^dd,^d) > xomin^d .and. x(ix^dd,^d) < xomax^d | .and. })
then
2565 patchwi(ix^d)=.true.
2566 volume_pe=volume_pe+
block%dvolume(ix^d)
2568 patchwi(ix^d)=.false.
2577 integer,
intent(in) :: ixi^
l,ixo^
l,iw
2578 double precision,
intent(in) :: x(ixi^s,1:
ndim)
2579 double precision :: w(ixi^s,nw+
nwauxio)
2580 logical,
intent(in) :: patchwi(ixi^s)
2582 double precision,
dimension(ixI^S,7-2*ndir:3) :: current
2583 double precision,
dimension(ixI^S,1:ndir) :: bvec,qvec
2585 integer :: ix^
d,idirmin0,idirmin,idir,jdir,kdir
2591 bvec(ixo^s,:)=w(ixo^s,mag(:))
2594 qvec(ixo^s,1:
ndir)=zero
2595 do idir=1,
ndir;
do jdir=idirmin,3;
do kdir=1,
ndir
2596 if(
lvc(idir,jdir,kdir)/=0)
then
2597 if(
lvc(idir,jdir,kdir)==1)
then
2598 qvec(ixo^s,idir)=qvec(ixo^s,idir)+current(ixo^s,jdir)*bvec(ixo^s,kdir)
2600 qvec(ixo^s,idir)=qvec(ixo^s,idir)-current(ixo^s,jdir)*bvec(ixo^s,kdir)
2603 end do;
end do;
end do
2605 {
do ix^db=ixomin^db,ixomax^db\}
2606 if(patchwi(ix^d))
then
2607 bm2=sum(bvec(ix^d,:)**2)
2608 if(bm2/=0.d0) bm2=1.d0/bm2
2610 bm2)*block%dvolume(ix^d)
2616 {
do ix^db=ixomin^db,ixomax^db\}
2624 {
do ix^db=ixomin^db,ixomax^db\}
2629 bvec(ixo^s,:)=w(ixo^s,mag(:))
2632 qvec(ixo^s,1:ndir)=zero
2633 do idir=1,ndir;
do jdir=idirmin,3;
do kdir=1,ndir
2634 if(lvc(idir,jdir,kdir)/=0)
then
2635 if(lvc(idir,jdir,kdir)==1)
then
2636 qvec(ixo^s,idir)=qvec(ixo^s,idir)+current(ixo^s,jdir)*bvec(ixo^s,kdir)
2638 qvec(ixo^s,idir)=qvec(ixo^s,idir)-current(ixo^s,jdir)*bvec(ixo^s,kdir)
2641 end do;
end do;
end do
2643 {
do ix^db=ixomin^db,ixomax^db\}
2645 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 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 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 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 mf_add_source_geom(qdt, dtfactor, 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.