73 integer,
allocatable ::
bp(:)
75 integer,
allocatable ::
ep(:)
77 integer,
allocatable ::
vp(:)
79 integer,
allocatable ::
jp(:)
105 double precision,
allocatable :: payload(:)
106 integer :: igrid, ipe
115 double precision :: q
117 double precision :: m
119 double precision :: time
121 double precision ::
dt
123 double precision :: x(3)
125 double precision :: u(3)
152 integer,
intent(inout) :: ngridvars
159 double precision,
intent(in) :: end_time
179 integer,
intent(in) :: nout, outgoing_ids(:), destinations(:)
180 logical,
intent(in) :: global_exchange
181 integer :: sc(0:npe-1),rc(0:npe-1),so(0:npe-1),ro(0:npe-1),cursor(0:npe-1)
182 integer :: p,j,k,nrecv,nreq,ngrow,idx,igrid_particle,ipe_particle,tag_s,tag_r
183 integer :: local_flags(2),global_flags(2)
184 logical :: neighbor_mask(0:npe-1)
186 sc=0;rc=0;neighbor_mask=.false.
190 if(p<0.or.p>=npe.or.p==
mype)
call mpistop(
'Invalid particle migration destination')
197 if(.not.global_exchange)
then
199 local_flags(2)=count(sc>0.and..not.neighbor_mask)
200 call mpi_allreduce(local_flags,global_flags,2,mpi_integer,mpi_sum,
icomm,
ierrmpi)
201 if(global_flags(1)==0)
then
210 if(global_exchange)
then
211 call mpi_alltoall(sc,1,mpi_integer,rc,1,mpi_integer,
icomm,
ierrmpi)
212 else if(global_flags(2)>0)
then
213 call mpi_alltoall(sc,1,mpi_integer,rc,1,mpi_integer,
icomm,
ierrmpi)
242 so(p)=so(p-1)+sc(p-1);ro(p)=ro(p-1)+rc(p-1)
246 p=destinations(j);cursor(p)=cursor(p)+1;k=cursor(p);idx=outgoing_ids(j)
255 tag_r=p*npe+
mype;k=ro(p)+1
264 tag_s=
mype*npe+p;k=so(p)+1
273 if(.not.global_exchange)
then
275 do k=so(p)+1,so(p)+sc(p)
284 if(global_exchange)
then
285 do k=so(p)+1,so(p)+sc(p)
292 do k=ro(p)+1,ro(p)+rc(p)
294 if(idx<1.or.idx>
size(
particle))
call mpistop(
'Received particle index out of bounds')
295 if(
associated(
particle(idx)%self))
call mpistop(
'Duplicate particle received')
301 if(ipe_particle/=
mype.or.igrid_particle<1)
call mpistop(
'Received particle has wrong owner')
309 integer :: j,idx,igrid_particle,ipe_particle,nout
310 integer :: outgoing_ids(max(1,nparticles_on_mype)),destinations(max(1,nparticles_on_mype))
312 do j=1,nparticles_on_mype
315 if(ipe_particle<0.or.igrid_particle<1)
call mpistop(
'Global relocation outside particle domain')
317 if(ipe_particle/=
mype)
then
318 nout=nout+1;outgoing_ids(nout)=idx;destinations(nout)=ipe_particle
326 integer :: j,idx,igrid_particle,ipe_particle,nout,ndestroy
327 integer :: outgoing_ids(max(1,nparticles_on_mype)),destinations(max(1,nparticles_on_mype))
328 integer :: destroyed(max(1,nparticles_on_mype))
329 logical :: BC_applied
331 do j=1,nparticles_on_mype
335 ndestroy=ndestroy+1;destroyed(ndestroy)=idx
341 if(igrid_particle==-1)
then
343 if(.not.bc_applied.or.igrid_particle==-1)
then
344 ndestroy=ndestroy+1;destroyed(ndestroy)=idx
349 if(
npe>1.and.ipe_particle/=
mype)
then
350 nout=nout+1;outgoing_ids(nout)=idx;destinations(nout)=ipe_particle
387 character(len=*),
intent(in) :: files(:)
398 do n = 1,
size(files)
399 open(
unitpar, file=trim(files(n)), status=
"old")
400 read(
unitpar, particles_list,
end=111)
410 integer,
parameter :: i8 = selected_int_kind(18)
411 integer(i8) :: seed(2)
413 character(len=20) :: strdata
436 dtheta = 2.0d0*dpi / 60.0d0
455 seed = [310952_i8, 8948923749821_i8]
456 call rng%set_seed(seed)
467 csv_header =
' time, dt, x1, x2, x3, u1, u2, u3,'
471 write(strdata,
"(a,a,a)")
' ', trim(prim_wnames(n)),
','
476 write(strdata,
"(a,i2.2,a)")
' pl', n,
','
483 write(strdata,
"(a,i2.2,a)")
' usrpl', n,
','
490 write(
csv_format,
'(A,I0,A,A)')
'(', 8 +
npayload,
'(es14.6,", "),', &
491 'i8.7,", ",i11.10,", ",i8.7)'
499 integer :: oldtypes(0:7), offsets(0:7), blocklengths(0:7)
501 oldtypes(0) = mpi_logical
502 oldtypes(1) = mpi_integer
503 oldtypes(2:7) = mpi_double_precision
510 offsets(1) = size_logical * blocklengths(0)
511 offsets(2) = offsets(1) + size_int * blocklengths(1)
512 offsets(3) = offsets(2) + size_double * blocklengths(2)
513 offsets(4) = offsets(3) + size_double * blocklengths(3)
514 offsets(5) = offsets(4) + size_double * blocklengths(4)
515 offsets(6) = offsets(5) + size_double * blocklengths(5)
516 offsets(7) = offsets(6) + size_double * blocklengths(6)
524 double precision,
intent(out) :: v(3)
525 double precision,
intent(in) :: velocity
526 double precision :: vtmp(3), vnorm
528 vtmp(1) = velocity *
rng%normal()
529 vtmp(2) = velocity *
rng%normal()
530 vtmp(3) = velocity *
rng%normal()
532 v =
rng%sphere(vnorm)
537 double precision,
intent(out) :: x(3)
539 call rng%unif_01_vec(x)
541 {^
d&x(^
d) = xprobmin^
d + x(^
d) * (xprobmax^
d - xprobmin^
d)\}
550 integer :: igrid, iigrid
554 do iigrid=1,igridstail; igrid=igrids(iigrid);
555 allocate(gridvars(igrid)%w(ixg^t,1:
ngridvars),gridvars(igrid)%wold(ixg^t,1:
ngridvars))
556 gridvars(igrid)%w = 0.0d0
557 gridvars(igrid)%wold = 0.0d0
573 integer :: iigrid, igrid
575 do iigrid=1,igridstail; igrid=igrids(iigrid);
576 deallocate(gridvars(igrid)%w,gridvars(igrid)%wold)
586 double precision :: E(ixG^T, ndir)
587 double precision :: B(ixG^T, ndir)
588 integer :: igrid, iigrid
590 do iigrid=1,igridstail; igrid=igrids(iigrid);
593 gridvars(igrid)%w(ixg^t,
ep(:)) = e
594 gridvars(igrid)%w(ixg^t,
bp(:)) = b
606 integer,
intent(in) :: igrid
607 double precision,
intent(in) :: w_mhd(ixG^T,nw)
608 double precision,
intent(inout) :: w_part(ixG^T,ngridvars)
610 double precision :: current(ixG^T,7-2*ndir:3)
611 double precision :: w(ixG^T,1:nw)
612 integer :: idirmin, idir
616 w(ixg^t,1:nw) = w_mhd(ixg^t,1:nw)
617 w_part(ixg^t,
bp(1):
bp(3)) = 0.0d0
618 w_part(ixg^t,
ep(1):
ep(3)) = 0.0d0
620 call phys_to_primitive(ixg^
ll,ixg^
ll,w,ps(igrid)%x)
623 w_part(ixg^t,
rhop) = w(ixg^t,iw_rho)
626 w_part(ixg^t,
vp(:)) = w(ixg^t,iw_mom(:))
631 w_part(ixg^t,
bp(idir))=w(ixg^t,iw_mag(idir))+ps(igrid)%B0(ixg^t,idir,0)
634 w_part(ixg^t,
bp(:)) = w(ixg^t,iw_mag(:))
640 w_part(ixg^t,
jp(:)) = current(ixg^t,:)
645 w_part(ixg^t,
ep(1)) = w_part(ixg^t,
bp(2)) * &
646 w(ixg^t,iw_mom(3)) - w_part(ixg^t,
bp(3)) * &
648 w_part(ixg^t,
ep(2)) = w_part(ixg^t,
bp(3)) * &
649 w(ixg^t,iw_mom(1)) - w_part(ixg^t,
bp(1)) * &
651 w_part(ixg^t,
ep(3)) = w_part(ixg^t,
bp(1)) * &
652 w(ixg^t,iw_mom(2)) - w_part(ixg^t,
bp(2)) * &
655 w_part(ixg^t,
ep(
r_)) = w_part(ixg^t,
bp(
phi_)) * &
656 w(ixg^t,iw_mom(
z_)) - w_part(ixg^t,
bp(
z_)) * &
658 w_part(ixg^t,
ep(
phi_)) = w_part(ixg^t,
bp(
z_)) * &
659 w(ixg^t,iw_mom(
r_)) - w_part(ixg^t,
bp(
r_)) * &
661 w_part(ixg^t,
ep(
z_)) = w_part(ixg^t,
bp(
r_)) * &
662 w(ixg^t,iw_mom(
phi_)) - w_part(ixg^t,
bp(
phi_)) * &
671 (current(ixg^t,2) * w_part(ixg^t,
bp(3)) - current(ixg^t,3) * w_part(ixg^t,
bp(2)))
673 (-current(ixg^t,1) * w_part(ixg^t,
bp(3)) + current(ixg^t,3) * w_part(ixg^t,
bp(1)))
675 (current(ixg^t,1) * w_part(ixg^t,
bp(2)) - current(ixg^t,2) * w_part(ixg^t,
bp(1)))
678 (current(ixg^t,
phi_) * w_part(ixg^t,
bp(
z_)) - current(ixg^t,
z_) * w_part(ixg^t,
bp(
phi_)))
680 (-current(ixg^t,
r_) * w_part(ixg^t,
bp(
z_)) + current(ixg^t,
z_) * w_part(ixg^t,
bp(
r_)))
682 (current(ixg^t,
r_) * w_part(ixg^t,
bp(
phi_)) - current(ixg^t,
phi_) * w_part(ixg^t,
bp(
r_)))
694 integer :: ixO^L, idirmin, ixI^L
695 double precision :: w(ixI^S,1:nw)
697 double precision :: current(ixI^S,7-2*ndir:3),bvec(ixI^S,1:ndir)
705 bvec(ixi^s,idir)=w(ixi^s,iw_mag(idir))+
block%B0(ixi^s,idir,0)
709 bvec(ixi^s,idir)=w(ixi^s,iw_mag(idir))
713 call curlvector(bvec,ixi^l,ixo^l,current,idirmin,idirmin0,ndir)
722 integer :: igrid, iigrid
726 do iigrid=1,igridstail; igrid=igrids(iigrid);
727 gridvars(igrid)%wold=gridvars(igrid)%w
746 integer :: steps_taken, nparticles_left
793 if (nparticles_left == 0 .and.
convert)
call mpistop(
'No particles left')
805 double precision,
intent(in) :: end_time
806 integer,
intent(out) :: steps_taken
818 steps_taken = steps_taken + 1
831 double precision,
intent(in) :: t_left
832 double precision,
intent(inout) :: dt_p
833 double precision :: n_steps
834 double precision,
parameter :: eps = 1d-10
836 n_steps = t_left / dt_p
838 if (n_steps < 1+eps)
then
841 else if (n_steps < 2-eps)
then
843 dt_p = 0.5d0 * t_left
854 integer,
intent(in) :: ix(ndir)
855 integer,
intent(in) :: igrid
856 double precision,
dimension(3),
intent(in) :: x
857 double precision,
intent(in) :: tloc
858 double precision,
dimension(ndir),
intent(out) :: vec
859 double precision,
dimension(ndir) :: vec1, vec2
860 double precision :: td, bb
868 ps(igrid)%x(ixg^t,1:
ndim),x,vec(idir))
874 ps(igrid)%x(ixg^t,1:
ndim),x,vec2(idir))
879 vec(:) = vec2(:) * (1.0d0 - td) + vec(:) * td
885 if (sqrt(sum(vec(:)**2)) .gt. 0.d0)
then
887 sum(gridvars(igrid)%w(ixg^t,ix(:))**2,dim=
ndim+1)*td &
888 +sum(gridvars(igrid)%wold(ixg^t,ix(:))**2,dim=
ndim+1)*(1.d0-td), &
889 ps(igrid)%x(ixg^t,1:
ndim),x,bb)
892 if (sqrt(sum(vec(:)**2)) .gt. 0.d0)
then
894 sum(gridvars(igrid)%w(ixg^t,ix(:))**2,dim=
ndim+1), &
895 ps(igrid)%x(ixg^t,1:
ndim),x,bb)
897 vec = vec/sqrt(sum(vec(:)**2))*sqrt(bb)
908 integer,
intent(in) :: igrid
909 double precision,
dimension(3),
intent(in) :: x
910 double precision,
intent(in) :: tloc
911 double precision,
dimension(ndir),
intent(out) :: b
912 double precision,
dimension(ndir) :: vec1, vec2, vec
913 double precision :: td, bb
923 ps(igrid)%x(ixg^t,1:
ndim),x,vec(idir))
929 ps(igrid)%x(ixg^t,1:
ndim),x,vec2(idir))
934 vec(:) = vec2(:) * (1.0d0 - td) + vec(:) * td
940 if (sqrt(sum(vec(:)**2)) .gt. 0.d0)
then
942 sum(gridvars(igrid)%w(ixg^t,
bp(:))**2,dim=
ndim+1)*td &
943 +sum(gridvars(igrid)%wold(ixg^t,
bp(:))**2,dim=
ndim+1)*(1.d0-td), &
944 ps(igrid)%x(ixg^t,1:
ndim),x,bb)
947 if (sqrt(sum(vec(:)**2)) .gt. 0.d0)
then
949 sum(gridvars(igrid)%w(ixg^t,
bp(:))**2,dim=
ndim+1), &
950 ps(igrid)%x(ixg^t,1:
ndim),x,bb)
952 vec = vec/sqrt(sum(vec(:)**2))*sqrt(bb)
968 integer,
intent(in) :: igrid
969 double precision,
dimension(3),
intent(in) :: x
970 double precision,
intent(in) :: tloc
971 double precision,
dimension(ndir),
intent(out) :: e
972 double precision,
dimension(ndir) :: vec1, vec2, vec
973 double precision,
dimension(ndir) :: vfluid, b
974 double precision,
dimension(ndir) :: current
975 double precision :: rho = 1.d0, rho2 = 1.d0
976 double precision :: td
989 call get_vec(
jp, igrid, x, tloc, current)
996 rho = rho2 * (1.0d0 - td) + rho * td
1020 double precision,
dimension(3),
intent(in) :: u
1021 double precision,
intent(out) :: lfac
1024 lfac = sqrt(1.0d0 + sum(u(:)**2)/
c_norm**2)
1034 double precision,
dimension(3),
intent(in) :: v
1035 double precision,
intent(out) :: lfac
1038 lfac = 1.0d0 / sqrt(1.0d0 - sum(v(:)**2)/
c_norm**2)
1048 double precision,
dimension(ndir),
intent(in) :: a,b
1049 double precision,
dimension(ndir),
intent(out) :: c
1055 c(1) = a(2)*b(3) - a(3)*b(2)
1056 c(2) = a(3)*b(1) - a(1)*b(3)
1057 c(3) = a(1)*b(2) - a(2)*b(1)
1063 call mpistop(
'geometry not implemented in cross(a,b,c)')
1066 call mpistop(
"cross in particles needs to be run with three components!")
1069 end subroutine cross
1074 integer,
intent(in) :: igrid,ixI^L, ixO^L
1075 double precision,
intent(in) :: gf(ixI^S)
1076 double precision,
intent(in) :: x(ixI^S,1:ndim)
1077 double precision,
intent(in) :: xloc(1:3)
1078 double precision,
intent(out) :: gfloc
1079 double precision :: xd^D, myq, dx1
1081 double precision :: c00, c10
1084 double precision :: c0, c1, c00, c10, c01, c11
1086 integer :: ic^D, ic1^D, ic2^D, idir
1091 ic^d = ceiling(dlog((xloc(^d)-xprobmin^d)*(
qstretch(ps(igrid)%level,^d)-one)/&
1092 dxfirst(ps(igrid)%level,^d)+one)/dlog(
qstretch(ps(igrid)%level,^d)))-&
1096 if(xloc(^d)<xprobmin^d+
xstretch^d)
then
1099 dxfirst(ps(igrid)%level,^d)+one)/dlog(
qstretch(ps(igrid)%level,^d)))-&
1101 else if(xloc(^d)>xprobmax^d-
xstretch^d)
then
1103 ic^d = ceiling(dlog((xloc(^d)-xprobmax^d+
xstretch^d)*(
qstretch(ps(igrid)%level,^d)-one)/&
1104 dxfirst(ps(igrid)%level,^d)+one)/dlog(
qstretch(ps(igrid)%level,^d)))-&
1119 if (x({ic^dd},^d) .lt. xloc(^d))
then
1128 if(ic1^d.lt.
ixglo^d+1 .or. ic2^d.gt.
ixghi^d-1)
then
1129 print *,
'direction: ',^d
1130 print *,
'position: ',xloc(1:ndim)
1131 print *,
'indices:', ic1^d,ic2^d
1132 call mpistop(
'Trying to interpolate from out of grid!')
1137 xd1 = (xloc(1)-x(ic11,1)) / (x(ic21,1) - x(ic11,1))
1138 gfloc = gf(ic11) * (1.0d0 - xd1) + gf(ic21) * xd1
1141 xd1 = (xloc(1)-x(ic11,ic12,1)) / (x(ic21,ic12,1) - x(ic11,ic12,1))
1142 xd2 = (xloc(2)-x(ic11,ic12,2)) / (x(ic11,ic22,2) - x(ic11,ic12,2))
1143 c00 = gf(ic11,ic12) * (1.0d0 - xd1) + gf(ic21,ic12) * xd1
1144 c10 = gf(ic11,ic22) * (1.0d0 - xd1) + gf(ic21,ic22) * xd1
1145 gfloc = c00 * (1.0d0 - xd2) + c10 * xd2
1148 xd1 = (xloc(1)-x(ic11,ic12,ic13,1)) / (x(ic21,ic12,ic13,1) - x(ic11,ic12,ic13,1))
1149 xd2 = (xloc(2)-x(ic11,ic12,ic13,2)) / (x(ic11,ic22,ic13,2) - x(ic11,ic12,ic13,2))
1150 xd3 = (xloc(3)-x(ic11,ic12,ic13,3)) / (x(ic11,ic12,ic23,3) - x(ic11,ic12,ic13,3))
1152 c00 = gf(ic11,ic12,ic13) * (1.0d0 - xd1) + gf(ic21,ic12,ic13) * xd1
1153 c10 = gf(ic11,ic22,ic13) * (1.0d0 - xd1) + gf(ic21,ic22,ic13) * xd1
1154 c01 = gf(ic11,ic12,ic23) * (1.0d0 - xd1) + gf(ic21,ic12,ic23) * xd1
1155 c11 = gf(ic11,ic22,ic23) * (1.0d0 - xd1) + gf(ic21,ic22,ic23) * xd1
1157 c0 = c00 * (1.0d0 - xd2) + c10 * xd2
1158 c1 = c01 * (1.0d0 - xd2) + c11 * xd2
1160 gfloc = c0 * (1.0d0 - xd3) + c1 * xd3
1169 double precision :: tpartc_avg, tpartc_int_avg, tpartc_io_avg, tpartc_com_avg, tpartc_grid_avg
1178 tpartc_avg = tpartc_avg/dble(
npe)
1179 tpartc_int_avg = tpartc_int_avg/dble(
npe)
1180 tpartc_io_avg = tpartc_io_avg/dble(
npe)
1181 tpartc_com_avg = tpartc_com_avg/dble(
npe)
1182 tpartc_grid_avg = tpartc_grid_avg/dble(
npe)
1183 write(*,
'(a,f12.3,a)')
' Particle handling took : ',
tpartc,
' sec'
1184 write(*,
'(a,f12.2,a)')
' Percentage: ',100.0d0*
tpartc/(
timeloop+smalldouble),
' %'
1185 write(*,
'(a,f12.3,a)')
' Particle IO took : ',tpartc_io_avg,
' sec'
1186 write(*,
'(a,f12.2,a)')
' Percentage: ',100.0d0*tpartc_io_avg/(
timeloop+smalldouble),
' %'
1187 write(*,
'(a,f12.3,a)')
' Particle COM took : ',tpartc_com_avg,
' sec'
1188 write(*,
'(a,f12.2,a)')
' Percentage: ',100.0d0*tpartc_com_avg/(
timeloop+smalldouble),
' %'
1189 write(*,
'(a,f12.3,a)')
' Particle integration took : ',tpartc_int_avg,
' sec'
1190 write(*,
'(a,f12.2,a)')
' Percentage: ',100.0d0*tpartc_int_avg/(
timeloop+smalldouble),
' %'
1191 write(*,
'(a,f12.3,a)')
' Particle init grid took : ',tpartc_grid_avg,
' sec'
1192 write(*,
'(a,f12.2,a)')
' Percentage: ',100.0d0*tpartc_grid_avg/(
timeloop+smalldouble),
' %'
1200 logical,
intent(out) :: file_exists
1201 character(len=std_len) :: filename
1202 integer :: mynpayload, mynparticles, pos, index_latest
1215 do index_latest=9999,0,-1
1216 write(filename,
"(a,a,i6.6,a)") trim(
restart_from_file(1:pos-8)),
'_particles',index_latest,
'.dat'
1217 INQUIRE(file=filename, exist=file_exists)
1218 if(file_exists)
exit
1220 if (.not. file_exists)
then
1221 write(*,*)
'WARNING: File '//trim(filename)//
' with particle data does not exist.'
1222 write(*,*)
'Initialising particles from user or default routines'
1224 open(unit=
unitparticles,file=filename,form=
'unformatted',action=
'read',status=
'unknown',access=
'stream')
1227 call mpistop(
'npayload in restart file does not match npayload in mod_particles')
1231 call mpi_bcast(file_exists,1,mpi_logical,0,
icomm,
ierrmpi)
1232 if (.not. file_exists)
return
1242 mynparticles = mynparticles + 1
1245 call mpi_bcast(mynparticles,1,mpi_integer,0,
icomm,
ierrmpi)
1257 integer :: index,igrid_particle,ipe_particle
1276 particle(index)%igrid = igrid_particle
1286 character(len=std_len) :: filename
1291 type(
particle_t),
allocatable,
dimension(:) :: send_particles
1292 type(
particle_t),
allocatable,
dimension(:) :: receive_particles
1293 double precision,
allocatable,
dimension(:,:) :: send_payload
1294 double precision,
allocatable,
dimension(:,:) :: receive_payload
1295 integer :: status(MPI_STATUS_SIZE)
1296 integer,
dimension(0:npe-1) :: receive_n_particles_for_output_from_ipe
1297 integer :: ipe, ipart, iipart, send_n_particles_for_output
1298 logical,
save :: file_exists=.false.
1299 integer :: snapshotnumber
1307 receive_n_particles_for_output_from_ipe(:) = 0
1310 if (
mype .eq. 0)
then
1311 write(filename,
"(a,a,i6.6,a)") trim(
base_filename),
'_particles',snapshotnumber,
'.dat'
1312 INQUIRE(file=filename, exist=file_exists)
1313 if (.not. file_exists)
then
1314 open(unit=
unitparticles,file=filename,form=
'unformatted',status=
'new',access=
'stream')
1316 open(unit=
unitparticles,file=filename,form=
'unformatted',status=
'replace',access=
'stream')
1327 if (
mype .ne. 0)
then
1331 allocate(send_particles(1:send_n_particles_for_output))
1332 allocate(send_payload(1:
npayload,1:send_n_particles_for_output))
1334 send_particles(iipart) =
particle(ipart)%self
1340 call mpi_recv(receive_n_particles_for_output_from_ipe(ipe),1,mpi_integer,ipe,ipe,
icomm,status,
ierrmpi)
1344 if (
mype .ne. 0)
then
1347 deallocate(send_particles)
1348 deallocate(send_payload)
1358 allocate(receive_particles(1:receive_n_particles_for_output_from_ipe(ipe)))
1359 allocate(receive_payload(1:
npayload,1:receive_n_particles_for_output_from_ipe(ipe)))
1360 call mpi_recv(receive_particles,receive_n_particles_for_output_from_ipe(ipe),
type_particle,ipe,ipe,
icomm,status,
ierrmpi)
1361 call mpi_recv(receive_payload,
npayload*receive_n_particles_for_output_from_ipe(ipe),mpi_double_precision,ipe,ipe,
icomm,status,
ierrmpi)
1362 do ipart=1,receive_n_particles_for_output_from_ipe(ipe)
1365 deallocate(receive_particles)
1366 deallocate(receive_payload)
1376 double precision :: mypayload(1:npayload)
1393 integer :: iipart, ipart, icomp
1394 character(len=std_len) :: filename
1395 character(len=1024) :: line, strdata
1398 if (
particle(ipart)%self%follow)
then
1403 write(strdata,
"(a,i2.2,a)")
'payload',icomp,
','
1404 line = trim(line)//trim(strdata)
1406 write(
unitparticles,
"(a,a,a)")
'time,dt,x1,x2,x3,u1,u2,u3,',trim(line),
'ipe,iteration,index'
1415 double precision,
intent(in) :: end_time
1417 double precision :: t_min_mype
1418 double precision :: local_selection(2),global_selection(2)
1419 integer :: ipart, iipart
1422 t_min_mype = bigdouble
1427 activate = (
particle(ipart)%self%time < end_time)
1428 t_min_mype = min(t_min_mype,
particle(ipart)%self%time)
1436 local_selection(1)=t_min_mype
1437 local_selection(2)=1.d0
1439 call mpi_allreduce(local_selection,global_selection,2,mpi_double_precision, &
1451 integer,
intent(in) :: index
1452 integer,
intent(out) :: igrid_particle, ipe_particle
1453 integer :: iipart,ipart,ipe_has_particle,ipe
1454 integer,
dimension(0:1) :: buff
1455 logical :: has_particle(0:npe-1)
1457 has_particle(:) = .false.
1459 if (
particle(ipart)%self%index == index)
then
1460 has_particle(
mype) = .true.
1465 if (has_particle(
mype))
then
1470 if (npe>0)
call mpi_allgather(has_particle(
mype),1,mpi_logical,has_particle,1,mpi_logical,
icomm,
ierrmpi)
1472 ipe_has_particle = -1
1474 if (has_particle(ipe) .eqv. .true.)
then
1475 ipe_has_particle = ipe
1480 if (ipe_has_particle .ne. -1)
then
1481 if (npe>0)
call mpi_bcast(buff,2,mpi_integer,ipe_has_particle,
icomm,
ierrmpi)
1482 igrid_particle=buff(0)
1483 ipe_particle = buff(1)
1496 double precision,
intent(in) :: x(3)
1497 integer,
intent(out) :: igrid_particle, ipe_particle
1498 integer :: ig(ndir,nlevelshi), ig_lvl(nlevelshi)
1499 integer :: idim, ic(ndim)
1517 do while (.not.branch%node%leaf)
1518 {ic(^
d)=ig(^
d,branch%node%level+1) - 2 * branch%node%ig^
d +2\}
1519 branch%node => branch%node%child({ic(^
d)})%node
1522 igrid_particle = branch%node%igrid
1523 ipe_particle = branch%node%ipe
1530 double precision,
dimension(ndim),
intent(in) :: x
1533 all(x < [ xprobmax^
d ])
1539 integer,
intent(in) :: igrid, ipart
1540 double precision :: x(
ndim), grid_rmin(
ndim), grid_rmax(
ndim)
1543 if (.not.
allocated(ps(igrid)%w))
then
1556 integer :: igrid, iigrid,ipe
1557 integer :: my_neighbor_type, i^D
1558 logical :: ipe_is_neighbor(0:npe-1)
1560 ipe_is_neighbor(:) = .false.
1561 do iigrid=1,igridstail; igrid=igrids(iigrid);
1564 if (i^d==0|.and.)
then
1567 my_neighbor_type=neighbor_type(i^d,igrid)
1569 select case (my_neighbor_type)
1570 case (neighbor_boundary)
1572 case (neighbor_coarse)
1573 call ipe_fc(i^d,igrid,ipe_is_neighbor)
1574 case (neighbor_sibling)
1575 call ipe_srl(i^d,igrid,ipe_is_neighbor)
1576 case (neighbor_fine)
1577 call ipe_cf(i^d,igrid,ipe_is_neighbor)
1585 ipe_is_neighbor(mype) = .false.
1590 if (ipe_is_neighbor(ipe))
then
1600 integer,
intent(in) :: i^D, igrid
1601 logical,
intent(inout) :: ipe_is_neighbor(0:npe-1)
1603 ipe_is_neighbor(neighbor(2,i^d,igrid)) = .true.
1609 integer,
intent(in) :: i^D, igrid
1610 logical,
intent(inout) :: ipe_is_neighbor(0:npe-1)
1612 ipe_is_neighbor(neighbor(2,i^d,igrid)) = .true.
1618 integer,
intent(in) :: i^D, igrid
1619 logical,
intent(inout) :: ipe_is_neighbor(0:npe-1)
1620 integer :: ic^D, inc^D
1622 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1625 ipe_is_neighbor( neighbor_child(2,inc^d,igrid) ) = .true.
1634 character(len=std_len) :: filename
1637 type(
particle_t),
allocatable,
dimension(:) :: send_particles
1638 double precision,
allocatable,
dimension(:,:) :: send_payload
1639 double precision :: tout
1640 integer :: send_n_particles_for_output, cc
1642 integer :: ipart,iipart
1649 send_n_particles_for_output = 0
1656 send_n_particles_for_output = send_n_particles_for_output + 1
1660 allocate(send_particles(1:send_n_particles_for_output))
1661 allocate(send_payload(
npayload,1:send_n_particles_for_output))
1668 send_particles(cc) =
particle(ipart)%self
1675 send_payload,
'ensemble')
1676 deallocate(send_particles)
1677 deallocate(send_payload)
1685 character(len=*),
intent(in) :: type
1686 double precision,
intent(in) :: tout
1687 integer,
intent(in) :: index
1688 integer :: nout, mysnapshot
1702 subroutine output_ensemble(send_n_particles_for_output,send_particles,send_payload,typefile)
1705 integer,
intent(in) :: send_n_particles_for_output
1706 type(
particle_t),
dimension(send_n_particles_for_output),
intent(in) :: send_particles
1707 double precision,
dimension(npayload,send_n_particles_for_output),
intent(in) :: send_payload
1708 character(len=*),
intent(in) :: typefile
1709 character(len=std_len) :: filename
1710 type(
particle_t),
allocatable,
dimension(:) :: receive_particles
1711 double precision,
allocatable,
dimension(:,:) :: receive_payload
1712 integer :: status(MPI_STATUS_SIZE)
1713 integer,
dimension(0:npe-1) :: receive_n_particles_for_output_from_ipe
1714 integer :: ipe, ipart, nout
1715 logical :: file_exists
1717 receive_n_particles_for_output_from_ipe(:) = 0
1719 call mpi_allgather(send_n_particles_for_output, 1, mpi_integer, &
1720 receive_n_particles_for_output_from_ipe, 1, mpi_integer,
icomm,
ierrmpi)
1723 if (sum(receive_n_particles_for_output_from_ipe(:)) == 0)
return
1730 if(typefile==
'destroy')
then
1731 write(filename,
"(a,a,i6.6,a)") trim(
base_filename) //
'_', &
1732 trim(typefile) //
'.csv'
1734 inquire(file=filename, exist=file_exists)
1736 if (.not. file_exists)
then
1744 write(filename,
"(a,a,i6.6,a)") trim(
base_filename) //
'_', &
1751 do ipart=1,send_n_particles_for_output
1757 allocate(receive_particles(1:receive_n_particles_for_output_from_ipe(ipe)))
1758 allocate(receive_payload(1:
npayload,1:receive_n_particles_for_output_from_ipe(ipe)))
1759 call mpi_recv(receive_particles,receive_n_particles_for_output_from_ipe(ipe),
type_particle,ipe,ipe,
icomm,status,
ierrmpi)
1760 call mpi_recv(receive_payload,
npayload*receive_n_particles_for_output_from_ipe(ipe),mpi_double_precision,ipe,ipe,
icomm,status,
ierrmpi)
1761 do ipart=1,receive_n_particles_for_output_from_ipe(ipe)
1764 deallocate(receive_particles)
1765 deallocate(receive_payload)
1775 character(len=std_len) :: filename
1776 integer :: ipart,iipart,ipe
1777 logical :: file_exists
1783 if (
particle(ipart)%self%follow)
then
1784 write(filename,
"(a,a,i6.6,a)") trim(
base_filename),
'_particle_', &
1786 inquire(file=filename, exist=file_exists)
1811 double precision,
intent(in) :: payload(npayload)
1812 integer,
intent(in) :: ipe
1813 integer,
intent(in) :: file_unit
1814 double precision :: x(3), u(3)
1827 x(:) = myparticle%x(:)
1837 write(file_unit,
csv_format) myparticle%time, myparticle%dt, x(1:3), &
1849 double precision,
intent(in) :: xp(1:3)
1850 double precision,
intent(out) :: xpcart(1:3)
1854 xpcart(1:3) = xp(1:3)
1856 xpcart(1) = xp(
r_)*cos(xp(
phi_))
1857 xpcart(2) = xp(
r_)*sin(xp(
phi_))
1860 xpcart(1) = xp(1)*sin(xp(2))*cos(xp(3))
1862 xpcart(2) = xp(1)*cos(xp(2))
1863 xpcart(3) = xp(1)*sin(xp(2))*sin(xp(3))}
1865 xpcart(2) = xp(1)*sin(xp(2))*sin(xp(3))
1866 xpcart(3) = xp(1)*cos(xp(2))}
1868 write(*,*)
"No converter for coordinate=",
coordinate
1879 double precision,
intent(in) :: xpcart(1:3)
1880 double precision,
intent(out) :: xp(1:3)
1881 double precision :: xx, yy, zz
1882 double precision :: rr, tth, pphi
1888 xp(
r_) = sqrt(xpcart(1)**2 + xpcart(2)**2)
1889 xp(
phi_) = atan2(xpcart(2),xpcart(1))
1890 if (xp(
phi_) .lt. 0.d0) xp(
phi_) = 2.0d0*dpi + xp(
phi_)
1900 rr = sqrt(xx**2 + yy**2 + zz**2)
1903 pphi = acos(xx/sqrt(xx**2+yy**2))
1905 pphi = 2.d0*dpi - acos(xx/sqrt(xx**2+yy**2))
1907 xp(1:3) = (/ rr, tth, pphi /)
1909 write(*,*)
"No converter for coordinate=",
coordinate
1920 double precision,
intent(in) :: xp(1:3),up(1:3)
1921 double precision,
intent(out) :: upcart(1:3)
1931 upcart(1) = up(1)*sin(xp(2))*cos(xp(3)) + up(2)*cos(xp(2))*cos(xp(3)) - up(3)*sin(xp(3))
1933 upcart(2) = up(1)*cos(xp(2)) - up(2)*sin(xp(2))
1934 upcart(3) = up(1)*sin(xp(2))*sin(xp(3)) + up(2)*cos(xp(2))*sin(xp(3)) + up(3)*cos(xp(3))}
1936 upcart(2) = up(1)*sin(xp(2))*sin(xp(3)) + up(2)*cos(xp(2))*sin(xp(3)) + up(3)*cos(xp(3))
1937 upcart(3) = up(1)*cos(xp(2)) - up(2)*sin(xp(2))}
1939 write(*,*)
"No converter for coordinate=",
coordinate
1950 double precision,
intent(in) :: xp(1:3),upcart(1:3)
1951 double precision,
intent(out) :: up(1:3)
1955 up(1:3) = upcart(1:3)
1957 up(
r_) = cos(xp(
phi_)) * upcart(1) + sin(xp(
phi_)) * upcart(2)
1958 up(
phi_) = -sin(xp(
phi_)) * upcart(1) + cos(xp(
phi_)) * upcart(2)
1962 up(1) = upcart(1)*sin(xp(2))*cos(xp(3)) + upcart(3)*sin(xp(2))*sin(xp(3)) + upcart(2)*cos(xp(2))
1963 up(2) = upcart(1)*cos(xp(2))*cos(xp(3)) + upcart(3)*cos(xp(2))*sin(xp(3)) - upcart(2)*sin(xp(2))
1964 up(3) = -upcart(1)*sin(xp(3)) + upcart(3)*cos(xp(3))}
1966 up(1) = upcart(1)*sin(xp(2))*cos(xp(3)) + upcart(2)*sin(xp(2))*sin(xp(3)) + upcart(3)*cos(xp(2))
1967 up(2) = upcart(1)*cos(xp(2))*cos(xp(3)) + upcart(2)*cos(xp(2))*sin(xp(3)) - upcart(3)*sin(xp(2))
1968 up(3) = -upcart(1)*sin(xp(3)) + upcart(2)*cos(xp(3))}
1970 write(*,*)
"No converter for coordinate=",
coordinate
1980 integer,
intent(in) :: igrid
1981 double precision,
intent(inout) :: xp(1:3)
1982 double precision :: xpmod(1:3)
1999 xpmod(phiind) = xp(phiind) + 2.d0*dpi
2002 xp(phiind) = xpmod(phiind)
2006 xpmod(phiind) = xp(phiind) - 2.d0*dpi
2009 xp(phiind) = xpmod(phiind)
2020 integer,
intent(in) :: igrid, ngh
2021 double precision,
intent(in) :: x(
ndim)
2022 double precision :: grid_rmin(
ndim), grid_rmax(
ndim)
2351 integer,
intent(inout) :: igrid_particle, ipe_particle
2352 logical,
intent(out) :: BC_applied
2355 bc_applied = .false.
2362 if (.not.
periodb(idim)) cycle
2366 if (particle%x(^
d) .lt. xprobmin^
d)
then
2367 particle%x(^
d) = particle%x(^
d) + (xprobmax^
d - xprobmin^
d)
2370 if (particle%x(^
d) .ge. xprobmax^
d)
then
2371 particle%x(^
d) = particle%x(^
d) - (xprobmax^
d - xprobmin^
d)
2387 integer,
intent(in) :: destroy_n_particles_mype
2388 integer,
dimension(1:destroy_n_particles_mype),
intent(in) :: particle_index_to_be_destroyed
2389 type(
particle_t),
dimension(destroy_n_particles_mype):: destroy_particles_mype
2390 double precision,
dimension(npayload,destroy_n_particles_mype):: destroy_payload_mype
2391 integer :: iipart,ipart,destroy_n_particles
2393 destroy_n_particles = 0
2396 do iipart=1,destroy_n_particles_mype;ipart=particle_index_to_be_destroyed(iipart);
2397 destroy_particles_mype(iipart) =
particle(ipart)%self
2401 call output_ensemble(destroy_n_particles_mype,destroy_particles_mype,destroy_payload_mype,
'destroy')
2404 call mpi_allreduce(destroy_n_particles_mype,destroy_n_particles,1,mpi_integer,mpi_sum,
icomm,
ierrmpi)
2406 destroy_n_particles = destroy_n_particles_mype
2411 do iipart=1,destroy_n_particles_mype;ipart=particle_index_to_be_destroyed(iipart);
2420 deallocate(
particle(ipart)%payload)
2429 integer,
intent(in) :: ipart
2439 integer,
intent(in) :: ipart
subroutine, public mpistop(message)
Exit MPI-AMRVAC with an error message.
Module for physical and numeric constants.
Module with basic grid data structures.
integer(kind=8) particle_mesh_epoch
Replicated forest generation: topology or ownership changes invalidate cached particle locations and ...
type(tree_node_ptr), dimension(:^d &), allocatable, save tree_root
Pointers to the coarse grid.
Module with geometry-related routines (e.g., divergence, curl).
integer, parameter spherical
integer, parameter cartesian
integer, parameter cylindrical
integer, parameter cartesian_expansion
integer, parameter cartesian_stretched
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...
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.
logical nocartesian
IO switches for conversion.
integer ixghi
Upper index of grid block arrays.
integer, parameter stretch_uni
Unidirectional stretching from a side.
integer domain_nx
number of cells for each dimension in level-one mesh
integer, parameter unitpar
file handle for IO
double precision global_time
The global simulation time.
double precision time_max
End time for the simulation.
double precision xstretch
physical extent of stretched border in symmetric stretching
integer, parameter ndim
Number of spatial dimensions for grid variables.
integer, parameter rpxmin
integer, dimension(:,:), allocatable nstretchedblocks
(even) number of (symmetrically) stretched blocks per level and dimension
character(len=std_len), dimension(:), allocatable par_files
Which par files are used as input.
integer icomm
The MPI communicator.
integer mype
The rank of the current MPI task.
integer block_nx
number of cells for each dimension in grid block excluding ghostcells
double precision dt
global time step
double precision length_convert_factor
Conversion factor for length unit.
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.
double precision, dimension(:), allocatable, parameter d
double precision, dimension(:,:), allocatable qstretch
Stretching factors and first cell size for each AMR level and dimension.
integer snapshotnext
IO: snapshot and collapsed views output numbers/labels.
integer npe
The number of MPI tasks.
logical time_advance
do time evolving
character(len=std_len) restart_from_file
If not 'unavailable', resume from snapshot with this base file name.
logical, dimension(ndim) periodb
True for dimensions with periodic boundaries.
double precision c_norm
Normalised speed of light.
logical b0field
split magnetic field as background B0 field
double precision, dimension(:,:), allocatable rnode
Corner coordinates.
integer nghostcells
Number of ghost cells surrounding a grid.
logical convert
If true and restart_from_file is given, convert snapshots to other file formats.
integer, dimension(ndim) stretch_type
What kind of stretching is used per dimension.
double precision, dimension(^nd) dxlevel
store unstretched cell size of current level
integer, parameter rpxmax
character(len=std_len) base_filename
Base file name for simulation output, which will be followed by a number.
integer, parameter stretch_symm
Symmetric stretching around the center.
integer r_
Indices for cylindrical coordinates FOR TESTS, negative value when not used:
double precision, dimension(:,:), allocatable dxfirst
integer, dimension(:,:), allocatable node
integer, parameter ixglo
Lower index of grid block arrays (always 1).
Module with shared functionality for all the particle movers.
subroutine get_maxwellian_velocity(v, velocity)
subroutine partcoord_from_cartesian(xp, xpcart)
Convert to noncartesian coordinates.
double precision, dimension(3) integrator_velocity_factor
Normalization factor for velocity in the integrator.
integer nparticles_per_cpu_hi
Maximum number of particles in one processor.
integer exchange_send_capacity
subroutine particle_get_current(w, ixil, ixol, idirmin, current)
Calculate idirmin and the idirmin:3 components of the common current array make sure that dxlevel(^D)...
integer nparticleshi
Maximum number of particles.
pure subroutine limit_dt_endtime(t_left, dt_p)
integer num_particles
Number of particles.
double precision const_dt_particles
If positive, a constant time step for the particles.
subroutine output_individual()
integer n_output_destroyed
Output count for ensembles of destroyed particles.
integer it_particles
Iteration number of paritcles.
subroutine fields_from_mhd(igrid, w_mhd, w_part)
Determine fields from MHD variables.
subroutine particles_params_read(files)
Read this module's parameters from a file.
double precision min_particle_time
Minimum time of all particles.
subroutine output_ensemble(send_n_particles_for_output, send_particles, send_payload, typefile)
subroutine get_uniform_pos(x)
logical write_individual
Whether to write individual particle output (followed particles).
subroutine write_particle_output()
subroutine init_particles_com()
Initialize communicators for particles.
logical function particle_in_igrid(ipart, igrid)
Quick check if particle is still in igrid.
integer, dimension(:), allocatable particles_on_mype
Array of identity numbers of particles in current processor.
double precision dtsave_particles
Time interval to save particles.
subroutine output_particle(myparticle, payload, ipe, file_unit)
subroutine update_gridvars()
update grid variables for particles
integer ngridvars
Number of variables for grid field.
type(particle_t), dimension(:), allocatable exchange_send
subroutine ipe_fc(id, igrid, ipe_is_neighbor)
subroutine get_efield(igrid, x, tloc, e)
recursive logical function point_in_igrid_ghostc(x, igrid, ngh)
Quick check if particle coordinate is inside igrid (ghost cells included, except the last ngh).
double precision particles_etah
subroutine destroy_particles(destroy_n_particles_mype, particle_index_to_be_destroyed)
clean up destroyed particles on all cores
integer(kind=8) particle_last_mesh_epoch
integer nusrpayload
Number of user-defined payload variables for a particle.
subroutine select_active_particles(end_time)
subroutine write_particles_snapshot()
double precision particles_eta
Resistivity.
subroutine particles_finish()
Finalize the particles module.
logical write_snapshot
Whether to write particle snapshots.
pure subroutine get_lfac(u, lfac)
Get Lorentz factor from relativistic momentum.
subroutine find_particle_ipe(x, igrid_particle, ipe_particle)
subroutine pull_particle_from_particles_on_mype(ipart)
logical particle_any_active
Cached global activity and last replicated forest generation.
subroutine init_particles_output()
pure subroutine get_lfac_from_velocity(v, lfac)
Get Lorentz factor from velocity.
integer integrator
Integrator to be used for particles.
integer, dimension(:), allocatable ep
Variable index for electric field.
subroutine handle_particles()
Let particles evolve in time. The routine also handles grid variables and output.
subroutine partvec_from_cartesian(xp, up, upcart)
Convert vector from Cartesian coordinates.
subroutine fill_gridvars_default
This routine fills the particle grid variables with the default for mhd, i.e. only E and B.
character(len=400) csv_header
Header string used in CSV files.
subroutine finish_gridvars()
Deallocate grid variables for particles.
subroutine ipe_srl(id, igrid, ipe_is_neighbor)
subroutine get_bfield(igrid, x, tloc, b)
integer npayload
Number of total payload variables for a particle.
integer, parameter unitparticles
integer, dimension(:), allocatable particles_active_on_mype
Array of identity numbers of active particles in current processor.
logical relativistic
Use a relativistic particle mover?
character(len=name_len) integrator_type_particles
String describing the particle integrator type.
subroutine set_neighbor_ipe()
subroutine time_spent_on_particles()
subroutine get_vec(ix, igrid, x, tloc, vec)
logical write_ensemble
Whether to write ensemble output.
character(len=name_len) interp_type_particles
String describing the particle interpolation type.
integer downsample_particles
Particle downsampling factor in CSV output.
subroutine locate_particle(index, igrid_particle, ipe_particle)
subroutine push_particle_into_particles_on_mype(ipart)
subroutine read_from_snapshot()
integer, dimension(:), allocatable exchange_ids
integer nparticles_active_on_mype
Number of active particles in current processor.
procedure(sub_define_additional_gridvars), pointer particles_define_additional_gridvars
subroutine partcoord_to_cartesian(xp, xpcart)
Convert position to Cartesian coordinates.
integer nparticles
Identity number and total number of particles.
integer, dimension(:), allocatable exchange_requests
recursive subroutine fix_phi_crossing(xp, igrid)
Fix particle position when crossing the 0,2pi boundary in noncartesian coordinates.
integer nparticles_on_mype
Number of particles in current processor.
integer, dimension(:), allocatable bp
Variable index for magnetic field.
subroutine comm_particles()
double precision tmax_particles
Time limit of particles.
type(particle_ptr), dimension(:), allocatable particle
subroutine particle_exchange(outgoing_ids, destinations, nout, global_exchange)
Exchange only migrating particles, reusing geometrically grown buffers. All ranks participate; a glob...
procedure(fun_destroy), pointer usr_destroy_particle
integer, dimension(:), allocatable vp
Variable index for fluid velocity.
procedure(sub_integrate), pointer particles_integrate
subroutine cross(a, b, c)
procedure(sub_fill_gridvars), pointer particles_fill_gridvars
double precision t_next_output
Time to write next particle output.
subroutine advance_particles(end_time, steps_taken)
Routine handles the particle evolution.
subroutine partvec_to_cartesian(xp, up, upcart)
Convert vector to Cartesian coordinates.
integer ndefpayload
Number of default payload variables for a particle.
subroutine particle_base_init()
Give initial values to parameters.
integer, dimension(:,:), allocatable exchange_status
integer, dimension(:), allocatable ipe_neighbor
integer igrid_working
set the current igrid for the particle integrator:
character(len=60) csv_format
Format string used in CSV files.
integer, dimension(:), allocatable jp
Variable index for current.
subroutine append_to_snapshot(myparticle, mypayload)
subroutine apply_periodb(particle, igrid_particle, ipe_particle, bc_applied)
integer ipart_working
set the current ipart for the particle integrator:
subroutine interpolate_var(igrid, ixil, ixol, gf, x, xloc, gfloc)
double precision particles_cfl
Particle CFL safety factor.
procedure(sub_fill_additional_gridvars), pointer particles_fill_additional_gridvars
subroutine ipe_cf(id, igrid, ipe_is_neighbor)
logical function particle_in_domain(x)
Check if particle is inside computational domain.
character(len=name_len) physics_type_particles
String describing the particle physics type.
subroutine init_gridvars()
Initialize grid variables for particles.
character(len=128) function make_particle_filename(tout, index, type)
subroutine comm_particles_global()
double precision, dimension(:,:), allocatable exchange_recv_payload
subroutine read_particles_snapshot(file_exists)
integer exchange_recv_capacity
double precision, dimension(:,:), allocatable exchange_send_payload
type(particle_t), dimension(:), allocatable exchange_recv
integer rhop
Variable index for density.
This module defines the procedures of a physics module. It contains function pointers for the various...
Module for pseudo random number generation. The internal pseudo random generator is the xoroshiro128p...
Writes D-1 slice, can do so in various formats, depending on slice_type.
subroutine get_igslice(dir, x, igslice)
double precision tpartc_int_0
double precision timeio_tot
double precision tpartc_com
double precision tpartc_grid_0
double precision tpartc_io
double precision timeloop
double precision tpartc_com0
double precision tpartc_grid
double precision tpartc_io_0
double precision tpartc_int
Module with all the methods that users can customize in AMRVAC.
procedure(particle_analytic), pointer usr_particle_analytic
procedure(particle_fields), pointer usr_particle_fields
Random number generator type, which contains the state.