132 integer :: nghostcellsCo, interpolation_order
133 integer :: nx^D, nxCo^D, ixG^L, i^D, idir
149 ixm^l=ixg^l^lsubnghostcells;
153 ixcogsmax^d=ixcogmax^d;
157 nx^d=ixmmax^d-ixmmin^d+1;
161 interpolation_order=1
163 interpolation_order=2
167 if (nghostcellsco+interpolation_order-1>
nghostcells)
then
168 call mpistop(
"interpolation order for prolongation in getbc too high")
174 ixs_srl_min^d(-1)=ixmmin^d
175 ixs_srl_min^d( 0)=ixmmin^d
178 ixs_srl_max^d( 0)=ixmmax^d
179 ixs_srl_max^d( 1)=ixmmax^d
182 ixr_srl_min^d( 0)=ixmmin^d
183 ixr_srl_min^d( 1)=ixmmax^d+1
185 ixr_srl_max^d( 0)=ixmmax^d
186 ixr_srl_max^d( 1)=ixgmax^d
188 ixs_r_min^d(-1)=ixcommin^d
189 ixs_r_min^d( 0)=ixcommin^d
192 ixs_r_max^d( 0)=ixcommax^d
193 ixs_r_max^d( 1)=ixcommax^d
196 ixr_r_min^d(1)=ixmmin^d
197 ixr_r_min^d(2)=ixmmin^d+nxco^d
198 ixr_r_min^d(3)=ixmmax^d+1
200 ixr_r_max^d(1)=ixmmin^d-1+nxco^d
201 ixr_r_max^d(2)=ixmmax^d
202 ixr_r_max^d(3)=ixgmax^d
204 ixs_p_min^d(0)=ixmmin^d-(interpolation_order-1)
205 ixs_p_min^d(1)=ixmmin^d-(interpolation_order-1)
206 ixs_p_min^d(2)=ixmmin^d+nxco^d-nghostcellsco-(interpolation_order-1)
207 ixs_p_min^d(3)=ixmmax^d+1-nghostcellsco-(interpolation_order-1)
208 ixs_p_max^d(0)=ixmmin^d-1+nghostcellsco+(interpolation_order-1)
209 ixs_p_max^d(1)=ixmmin^d-1+nxco^d+nghostcellsco+(interpolation_order-1)
210 ixs_p_max^d(2)=ixmmax^d+(interpolation_order-1)
211 ixs_p_max^d(3)=ixmmax^d+(interpolation_order-1)
213 ixr_p_min^d(0)=ixcommin^d-nghostcellsco-(interpolation_order-1)
214 ixr_p_min^d(1)=ixcommin^d-(interpolation_order-1)
215 ixr_p_min^d(2)=ixcommin^d-nghostcellsco-(interpolation_order-1)
216 ixr_p_min^d(3)=ixcommax^d+1-(interpolation_order-1)
218 ixr_p_max^d(1)=ixcommax^d+nghostcellsco+(interpolation_order-1)
219 ixr_p_max^d(2)=ixcommax^d+(interpolation_order-1)
220 ixr_p_max^d(3)=ixcommax^d+nghostcellsco+(interpolation_order-1)
225 allocate(pole_buf%ws(ixgs^t,nws))
228 { ixs_srl_stg_min^d(idir,-1)=ixmmin^d-
kr(idir,^d)
230 ixs_srl_stg_min^d(idir,0) =ixmmin^d-
kr(idir,^d)
231 ixs_srl_stg_max^d(idir,0) =ixmmax^d
232 ixs_srl_stg_min^d(idir,1) =ixmmax^d-
nghostcells+1-
kr(idir,^d)
233 ixs_srl_stg_max^d(idir,1) =ixmmax^d
235 ixr_srl_stg_min^d(idir,-1)=1-
kr(idir,^d)
237 ixr_srl_stg_min^d(idir,0) =ixmmin^d-
kr(idir,^d)
238 ixr_srl_stg_max^d(idir,0) =ixmmax^d
239 ixr_srl_stg_min^d(idir,1) =ixmmax^d+1-
kr(idir,^d)
240 ixr_srl_stg_max^d(idir,1) =ixgmax^d
242 ixs_r_stg_min^d(idir,-1)=ixcommin^d-
kr(idir,^d)
244 ixs_r_stg_min^d(idir,0) =ixcommin^d-
kr(idir,^d)
245 ixs_r_stg_max^d(idir,0) =ixcommax^d
246 ixs_r_stg_min^d(idir,1) =ixcommax^d+1-
nghostcells-
kr(idir,^d)
247 ixs_r_stg_max^d(idir,1) =ixcommax^d
249 ixr_r_stg_min^d(idir,0)=1-
kr(idir,^d)
251 ixr_r_stg_min^d(idir,1)=ixmmin^d-
kr(idir,^d)
252 ixr_r_stg_max^d(idir,1)=ixmmin^d-1+nxco^d
253 ixr_r_stg_min^d(idir,2)=ixmmin^d+nxco^d-
kr(idir,^d)
254 ixr_r_stg_max^d(idir,2)=ixmmax^d
255 ixr_r_stg_min^d(idir,3)=ixmmax^d+1-
kr(idir,^d)
256 ixr_r_stg_max^d(idir,3)=ixgmax^d
261 ixs_p_stg_min^d(idir,0)=ixmmin^d-1
262 ixs_p_stg_max^d(idir,0)=ixmmin^d-1+nghostcellsco
263 ixs_p_stg_min^d(idir,1)=ixmmin^d-1
264 ixs_p_stg_max^d(idir,1)=ixmmin^d-1+nxco^d+nghostcellsco
265 ixs_p_stg_min^d(idir,2)=ixmmax^d-nxco^d-nghostcellsco
266 ixs_p_stg_max^d(idir,2)=ixmmax^d
267 ixs_p_stg_min^d(idir,3)=ixmmax^d-nghostcellsco
268 ixs_p_stg_max^d(idir,3)=ixmmax^d
270 ixr_p_stg_min^d(idir,0)=ixcommin^d-1-nghostcellsco
271 ixr_p_stg_max^d(idir,0)=ixcommin^d-1
272 ixr_p_stg_min^d(idir,1)=ixcommin^d-1
273 ixr_p_stg_max^d(idir,1)=ixcommax^d+nghostcellsco
274 ixr_p_stg_min^d(idir,2)=ixcommin^d-1-nghostcellsco
275 ixr_p_stg_max^d(idir,2)=ixcommax^d
276 ixr_p_stg_min^d(idir,3)=ixcommax^d+1-1
277 ixr_p_stg_max^d(idir,3)=ixcommax^d+nghostcellsco
282 ixs_p_stg_min^d(idir,0)=ixmmin^d
283 ixs_p_stg_max^d(idir,0)=ixmmin^d-1+nghostcellsco+(interpolation_order-1)
284 ixs_p_stg_min^d(idir,1)=ixmmin^d
285 ixs_p_stg_max^d(idir,1)=ixmmin^d-1+nxco^d+nghostcellsco+(interpolation_order-1)
286 ixs_p_stg_min^d(idir,2)=ixmmax^d+1-nxco^d-nghostcellsco-(interpolation_order-1)
287 ixs_p_stg_max^d(idir,2)=ixmmax^d
288 ixs_p_stg_min^d(idir,3)=ixmmax^d+1-nghostcellsco-(interpolation_order-1)
289 ixs_p_stg_max^d(idir,3)=ixmmax^d
291 ixr_p_stg_min^d(idir,0)=ixcommin^d-nghostcellsco-(interpolation_order-1)
292 ixr_p_stg_max^d(idir,0)=ixcommin^d-1
293 ixr_p_stg_min^d(idir,1)=ixcommin^d
294 ixr_p_stg_max^d(idir,1)=ixcommax^d+nghostcellsco+(interpolation_order-1)
295 ixr_p_stg_min^d(idir,2)=ixcommin^d-nghostcellsco-(interpolation_order-1)
296 ixr_p_stg_max^d(idir,2)=ixcommax^d
297 ixr_p_stg_min^d(idir,3)=ixcommax^d+1
298 ixr_p_stg_max^d(idir,3)=ixcommax^d+nghostcellsco+(interpolation_order-1)
307 sizes_srl_send_stg(idir,i^d)={(ixs_srl_stg_max^d(idir,i^d)-ixs_srl_stg_min^d(idir,i^d)+1)|*}
308 sizes_srl_recv_stg(idir,i^d)={(ixr_srl_stg_max^d(idir,i^d)-ixr_srl_stg_min^d(idir,i^d)+1)|*}
309 sizes_r_send_stg(idir,i^d)={(ixs_r_stg_max^d(idir,i^d)-ixs_r_stg_min^d(idir,i^d)+1)|*}
319 sizes_r_recv_stg(idir,i^d)={(ixr_r_stg_max^d(idir,i^d)-ixr_r_stg_min^d(idir,i^d)+1)|*}
320 sizes_p_send_stg(idir,i^d)={(ixs_p_stg_max^d(idir,i^d)-ixs_p_stg_min^d(idir,i^d)+1)|*}
321 sizes_p_recv_stg(idir,i^d)={(ixr_p_stg_max^d(idir,i^d)-ixr_p_stg_min^d(idir,i^d)+1)|*}
396 subroutine getbc(time,qdt,psb,nwstart,nwbc)
405 double precision,
intent(in) :: time, qdt
406 type(state),
target :: psb(max_blocks)
407 integer,
intent(in) :: nwstart
408 integer,
intent(in) :: nwbc
410 double precision :: tbc(3)
411 integer :: nwhead, nwtail
412 integer :: iigrid, igrid, isizes, i^D
413 integer :: isend_buf(npwbuf), ipwbuf, nghostcellsco
414 integer :: flushed_send_c, flushed_send_srl, flushed_send_r, flushed_send_p
416 integer :: ibuf_start, ibuf_next
418 integer,
dimension(1) :: shapes
424 nwtail=nwstart+nwbc-1
433 do iigrid=1,igridstail; igrid=igrids(iigrid);
434 if(any(neighbor_type(:^d&,igrid)==neighbor_coarse))
then
468 do iigrid=1,igridstail; igrid=igrids(iigrid);
470 if (skip_direction([ i^d ])) cycle
471 select case (neighbor_type(i^d,igrid))
472 case (neighbor_sibling)
473 call bc_recv_srl(igrid,i^d)
475 call bc_recv_restrict(igrid,i^d)
481 do iigrid=1,igridstail; igrid=igrids(iigrid);
483 if(skip_direction([ i^d ])) cycle
484 select case (neighbor_type(i^d,igrid))
485 case (neighbor_sibling)
486 call bc_send_srl(igrid,i^d)
487 case (neighbor_coarse)
488 call bc_send_restrict(igrid,i^d)
495 if(stagger_grid)
then
503 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
507 do iigrid=1,igridstail; igrid=igrids(iigrid);
509 if(skip_direction([ i^d ])) cycle
510 select case (neighbor_type(i^d,igrid))
511 case(neighbor_sibling)
512 call bc_fill_srl(igrid,i^d)
513 case(neighbor_coarse)
514 call bc_fill_restrict(igrid,i^d)
520 if(stagger_grid)
then
524 do iigrid=1,igridstail; igrid=igrids(iigrid);
526 if (skip_direction([ i^d ])) cycle
527 select case (neighbor_type(i^d,igrid))
528 case (neighbor_sibling)
529 call bc_fill_srl_stg(igrid,i^d)
531 call bc_fill_restrict_stg(igrid,i^d)
547 do iigrid=1,igridstail; igrid=igrids(iigrid);
549 if (skip_direction([ i^d ])) cycle
550 if (neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_recv_prolong(igrid,i^d)
554 do iigrid=1,igridstail; igrid=igrids(iigrid);
556 if (skip_direction([ i^d ])) cycle
557 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_send_prolong(igrid,i^d)
564 if(stagger_grid)
then
570 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
575 do iigrid=1,igridstail; igrid=igrids(iigrid);
577 if (skip_direction([ i^d ])) cycle
578 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_fill_prolong(igrid,i^d)
583 if(stagger_grid)
then
586 do iigrid=1,igridstail; igrid=igrids(iigrid);
588 if (skip_direction([ i^d ])) cycle
589 if(neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_fill_prolong_stg(igrid,i^d)
595 do iigrid=1,igridstail; igrid=igrids(iigrid);
596 call gc_prolong(igrid)
602 if(
associated(usr_prepare_boundary))
then
603 call usr_prepare_boundary(time, qdt)
606 do iigrid=1,igridstail; igrid=igrids(iigrid);
607 if(.not.phyboundblock(igrid)) cycle
608 call fill_boundary_after_gc(igrid)
614 if(
bcphys.and.
associated(phys_boundary_adjust))
then
616 do iigrid=1,igridstail; igrid=igrids(iigrid);
617 if(.not.phyboundblock(igrid)) cycle
618 call phys_boundary_adjust(igrid,psb)
624 time_bc=time_bc+timer_close(tbc)
629 integer,
intent(in) :: nrequest
630 integer,
intent(inout) :: requests(:)
631 integer,
intent(inout) :: statuses(:,:)
633 if (ghostcell_comm_batched)
then
634 call waitall_range(1,nrequest,requests,statuses)
636 call mpi_waitall(nrequest,requests,statuses,ierrmpi)
640 subroutine waitall_range(ifirst,ilast,requests,statuses)
641 integer,
intent(in) :: ifirst, ilast
642 integer,
intent(inout) :: requests(:)
643 integer,
intent(inout) :: statuses(:,:)
645 integer :: irequest,nwait
647 do irequest=ifirst,ilast,ghostcell_comm_batch_size
648 nwait=min(ghostcell_comm_batch_size,ilast-irequest+1)
649 call mpi_waitall(nwait,requests(irequest:irequest+nwait-1),&
650 statuses(:,irequest:irequest+nwait-1),ierrmpi)
652 end subroutine waitall_range
654 subroutine waitall_pending(nrequest,nwaited,requests,statuses)
655 integer,
intent(in) :: nrequest
656 integer,
intent(inout) :: nwaited
657 integer,
intent(inout) :: requests(:)
658 integer,
intent(inout) :: statuses(:,:)
660 if (nrequest>nwaited)
then
661 if (ghostcell_comm_batched)
then
662 call waitall_range(nwaited+1,nrequest,requests,statuses)
664 call mpi_waitall(nrequest-nwaited,requests(nwaited+1:nrequest),&
665 statuses(:,nwaited+1:nrequest),ierrmpi)
669 end subroutine waitall_pending
671 subroutine wait_send_batch(nrequest,nwaited,requests,statuses)
672 integer,
intent(in) :: nrequest
673 integer,
intent(inout) :: nwaited
674 integer,
intent(inout) :: requests(:)
675 integer,
intent(inout) :: statuses(:,:)
677 if (ghostcell_comm_batched .and. &
678 nrequest-nwaited >= ghostcell_comm_batch_size)
then
679 call waitall_range(nwaited+1,nrequest,requests,statuses)
682 end subroutine wait_send_batch
684 logical function skip_direction(dir)
685 integer,
intent(in) :: dir(^ND)
687 if (all(dir == 0))
then
688 skip_direction = .true.
690 skip_direction = .false.
692 end function skip_direction
695 subroutine fill_boundary_after_gc(igrid)
697 integer,
intent(in) :: igrid
699 integer :: idims,iside,i^D,k^L,ixB^L,ixO^L
700 logical :: has_eos_bc
706 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
713 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,igrid)==1)
714 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,igrid)==1)}
716 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,0,igrid)==1)
717 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,0,igrid)==1)
718 kmin3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0,-1,igrid)==1)
719 kmax3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0, 1,igrid)==1)}
720 ixbmin^d=ixglo^d+kmin^d*nghostcells;
721 ixbmax^d=ixghi^d-kmax^d*nghostcells;
723 i^d=kr(^d,idims)*(2*iside-3);
724 if (aperiodb(idims))
then
725 if (neighbor_type(i^d,igrid) /= neighbor_boundary .and. &
726 .not. psb(igrid)%is_physical_boundary(2*idims-2+iside)) cycle
728 if (neighbor_type(i^d,igrid) /= neighbor_boundary) cycle
737 call bc_phys(iside,idims,time,qdt,psb(igrid),ixg^ll,ixb^l)
748 ixomin^dd=ixbmax^d+1-nghostcells^d%ixOmin^dd=ixbmin^dd;
752 ixomax^dd=ixbmin^d-1+nghostcells^d%ixOmax^dd=ixbmax^dd;
760 end subroutine fill_boundary_after_gc
763 subroutine bc_recv_srl(igrid,i^D)
764 integer,
intent(in) :: igrid,i^D
766 integer :: ipe_neighbor
768 ipe_neighbor=neighbor(2,i^d,igrid)
769 if (ipe_neighbor/=mype)
then
771 itag=(3**^nd+4**^nd)*(igrid-1)+{(i^d+1)*3**(^d-1)+}
774 if(stagger_grid)
then
782 end subroutine bc_recv_srl
785 subroutine bc_recv_restrict(igrid,i^D)
786 integer,
intent(in) :: igrid,i^D
788 integer :: ic^D,inc^D,ipe_neighbor
790 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
791 inc^db=2*i^db+ic^db\}
792 ipe_neighbor=neighbor_child(2,inc^d,igrid)
793 if (ipe_neighbor/=mype)
then
795 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
796 call mpi_irecv(psb(igrid)%w,1,
type_recv_r(inc^d), &
798 if(stagger_grid)
then
801 mpi_double_precision,ipe_neighbor,itag, &
808 end subroutine bc_recv_restrict
811 subroutine bc_send_srl(igrid,i^D)
812 integer,
intent(in) :: igrid,i^D
814 integer :: n_i^D,ipole,idir,ineighbor,ipe_neighbor,ixS^L
816 ipe_neighbor=neighbor(2,i^d,igrid)
817 if(ipe_neighbor/=mype)
then
818 ineighbor=neighbor(1,i^d,igrid)
819 ipole=neighbor_pole(i^d,igrid)
823 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
827 if(stagger_grid)
then
834 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
847 n_i^d=i^d^d%n_i^dd=-i^dd;\}
849 if (isend_buf(ipwbuf)/=0)
then
852 deallocate(pwbuf(ipwbuf)%w)
854 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
855 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
858 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
859 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
860 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
863 ipwbuf=1+modulo(ipwbuf,
npwbuf)
864 if(stagger_grid)
then
871 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
883 end subroutine bc_send_srl
886 subroutine bc_send_restrict(igrid,i^D)
887 integer,
intent(in) :: igrid,i^D
889 integer :: ic^D,n_inc^D,ipole,idir,ineighbor,ipe_neighbor,ixS^L
891 ipe_neighbor=neighbor(2,i^d,igrid)
892 if(ipe_neighbor/=mype)
then
893 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
894 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
895 ineighbor=neighbor(1,i^d,igrid)
896 ipole=neighbor_pole(i^d,igrid)
900 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
904 if(stagger_grid)
then
911 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
916 mpi_double_precision,ipe_neighbor,itag, &
925 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
927 if(isend_buf(ipwbuf)/=0)
then
930 deallocate(pwbuf(ipwbuf)%w)
932 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
933 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psc(igrid)%w,
ixcog^l,ixs^l,ipole)
936 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
937 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
938 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
941 ipwbuf=1+modulo(ipwbuf,
npwbuf)
942 if(stagger_grid)
then
949 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
954 mpi_double_precision,ipe_neighbor,itag, &
962 end subroutine bc_send_restrict
965 subroutine bc_fill_srl(igrid,i^D)
966 integer,
intent(in) :: igrid,i^D
968 integer :: ineighbor,ipe_neighbor,ipole,ixS^L,ixR^L,n_i^D,idir
970 ipe_neighbor=neighbor(2,i^d,igrid)
971 if(ipe_neighbor==mype)
then
972 ineighbor=neighbor(1,i^d,igrid)
973 ipole=neighbor_pole(i^d,igrid)
978 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
979 psb(igrid)%w(ixs^s,nwhead:nwtail)
980 if(stagger_grid)
then
984 psb(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
991 n_i^d=i^d^d%n_i^dd=-i^dd;\}
994 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
995 if(stagger_grid)
then
999 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^l,psb(igrid)%ws,ixgs^ll,ixs^l,idir,ipole)
1005 end subroutine bc_fill_srl
1008 subroutine bc_fill_restrict(igrid,i^D)
1009 integer,
intent(in) :: igrid,i^D
1011 integer :: ic^D,n_inc^D,ixS^L,ixR^L,ipe_neighbor,ineighbor,ipole,idir
1013 ipe_neighbor=neighbor(2,i^d,igrid)
1014 if(ipe_neighbor==mype)
then
1015 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1016 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1017 ineighbor=neighbor(1,i^d,igrid)
1018 ipole=neighbor_pole(i^d,igrid)
1020 n_inc^d=-2*i^d+ic^d;
1023 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
1024 psc(igrid)%w(ixs^s,nwhead:nwtail)
1025 if(stagger_grid)
then
1029 psb(ineighbor)%ws(ixr^s,idir)=psc(igrid)%ws(ixs^s,idir)
1036 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
1039 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^l,psc(igrid)%w,
ixcog^l,ixs^l,ipole)
1040 if(stagger_grid)
then
1045 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^l,psc(igrid)%ws,
ixcogs^l,ixs^l,idir,ipole)
1051 end subroutine bc_fill_restrict
1054 subroutine bc_fill_srl_stg(igrid,i^D)
1055 integer,
intent(in) :: igrid,i^D
1057 integer :: ixS^L,ixR^L,n_i^D,idir,ineighbor,ipe_neighbor,ipole
1059 ipe_neighbor=neighbor(2,i^d,igrid)
1060 if(ipe_neighbor/=mype)
then
1061 ineighbor=neighbor(1,i^d,igrid)
1062 ipole=neighbor_pole(i^d,igrid)
1074 shape=shape(psb(igrid)%ws(ixs^s,idir)))
1080 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1088 shape=shape(psb(igrid)%ws(ixs^s,idir)))
1090 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^l,pole_buf%ws,ixgs^ll,ixs^l,idir,ipole)
1095 end subroutine bc_fill_srl_stg
1098 subroutine bc_fill_restrict_stg(igrid,i^D)
1099 integer,
intent(in) :: igrid,i^D
1101 integer :: ipole,ic^D,inc^D,ineighbor,ipe_neighbor,ixS^L,ixR^L,n_i^D,idir
1103 ipole=neighbor_pole(i^d,igrid)
1106 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1107 inc^db=2*i^db+ic^db\}
1108 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1109 if(ipe_neighbor/=mype)
then
1110 ineighbor=neighbor_child(1,inc^d,igrid)
1117 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1123 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1124 inc^db=2*i^db+ic^db\}
1125 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1126 if(ipe_neighbor/=mype)
then
1127 ineighbor=neighbor_child(1,inc^d,igrid)
1130 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1140 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1141 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^
l,pole_buf%ws,ixgs^ll,ixr^
l,idir,ipole)
1148 end subroutine bc_fill_restrict_stg
1151 subroutine bc_recv_prolong(igrid,i^D)
1152 integer,
intent(in) :: igrid,i^D
1154 integer :: ic^D,ipe_neighbor,inc^D
1156 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1157 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1159 ipe_neighbor=neighbor(2,i^d,igrid)
1160 if (ipe_neighbor/=mype)
then
1163 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
1164 call mpi_irecv(psc(igrid)%w,1,
type_recv_p(inc^d), &
1166 if(stagger_grid)
then
1169 mpi_double_precision,ipe_neighbor,itag,&
1175 end subroutine bc_recv_prolong
1178 subroutine bc_send_prolong(igrid,i^D)
1179 integer,
intent(in) :: igrid,i^D
1181 integer :: ic^D,inc^D,n_i^D,n_inc^D,ineighbor,ipe_neighbor,ixS^L,ipole,idir
1183 ipole=neighbor_pole(i^d,igrid)
1185 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1186 inc^db=2*i^db+ic^db\}
1187 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1188 if(ipe_neighbor/=mype)
then
1189 ineighbor=neighbor_child(1,inc^d,igrid)
1194 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1195 call mpi_isend(psb(igrid)%w,1,
type_send_p(inc^d), &
1198 if(stagger_grid)
then
1205 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1206 ibuf_start=ibuf_next
1210 mpi_double_precision,ipe_neighbor,itag, &
1219 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1221 if(isend_buf(ipwbuf)/=0)
then
1224 deallocate(pwbuf(ipwbuf)%w)
1226 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
1227 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
1230 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1231 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
1232 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
1235 ipwbuf=1+modulo(ipwbuf,
npwbuf)
1236 if(stagger_grid)
then
1243 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1244 ibuf_start=ibuf_next
1248 mpi_double_precision,ipe_neighbor,itag, &
1257 end subroutine bc_send_prolong
1260 subroutine bc_fill_prolong(igrid,i^D)
1261 integer,
intent(in) :: igrid,i^D
1263 integer :: ipe_neighbor,ineighbor,ixS^L,ixR^L,ic^D,inc^D,n_i^D,n_inc^D,ipole,idir
1265 ipole=neighbor_pole(i^d,igrid)
1268 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1269 inc^db=2*i^db+ic^db\}
1270 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1271 if(ipe_neighbor==mype)
then
1273 ineighbor=neighbor_child(1,inc^d,igrid)
1277 psc(ineighbor)%w(ixr^s,nwhead:nwtail) &
1278 =psb(igrid)%w(ixs^s,nwhead:nwtail)
1279 if(stagger_grid)
then
1283 psc(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
1289 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1290 inc^db=2*i^db+ic^db\}
1291 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1292 if(ipe_neighbor==mype)
then
1294 ineighbor=neighbor_child(1,inc^d,igrid)
1297 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1300 call pole_copy(psc(ineighbor)%w,
ixcog^
l,ixr^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
1301 if(stagger_grid)
then
1305 call pole_copy_stg(psc(ineighbor)%ws,
ixcogs^
l,ixr^
l,psb(igrid)%ws,ixgs^ll,ixs^
l,idir,ipole)
1311 end subroutine bc_fill_prolong
1313 subroutine gc_prolong(igrid)
1314 integer,
intent(in) :: igrid
1316 integer :: i^D,idims,iside
1317 logical,
dimension(-1:1^D&) :: NeedProlong
1321 if (skip_direction([ i^d ])) cycle
1322 if (neighbor_type(i^d,igrid)==neighbor_coarse)
then
1323 call bc_prolong(igrid,i^d)
1324 needprolong(i^d)=.true.
1327 if(stagger_grid)
then
1338 if (needprolong(i^dd))
call bc_prolong_stg(igrid,i^dd,needprolong)
1349 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1355 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1361 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1367 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1370 end subroutine gc_prolong
1373 subroutine bc_fill_prolong_stg(igrid,i^D)
1374 integer,
intent(in) :: igrid,i^D
1376 integer :: ipe_neighbor,ineighbor,ipole,ixR^L,ic^D,inc^D,n_inc^D,idir
1378 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1379 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1381 ipe_neighbor=neighbor(2,i^d,igrid)
1382 if(ipe_neighbor/=mype)
then
1383 ineighbor=neighbor(1,i^d,igrid)
1384 ipole=neighbor_pole(i^d,igrid)
1393 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1400 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
1408 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1409 call pole_copy_stg(psc(igrid)%ws,
ixcogs^l,ixr^l,pole_buf%ws,ixgs^ll,ixr^l,idir,ipole)
1415 end subroutine bc_fill_prolong_stg
1418 subroutine bc_prolong(igrid,i^D)
1422 double precision :: dxFi^D, dxCo^D, xFimin^D, xComin^D, invdxCo^D
1423 integer :: i^D,igrid
1424 integer :: ixFi^L,ixCo^L,ii^D, idims,iside,ixB^L
1427 dxfi^d=rnode(rpdx^d_,igrid);
1429 invdxco^d=1.d0/dxco^d;
1435 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1436 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1438 if(phyboundblock(igrid).and.
bcphys)
then
1441 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1442 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1446 if(neighbor_type(-1,0,0,igrid)==neighbor_boundary .or. &
1447 neighbor_type(1,0,0,igrid)==neighbor_boundary)
then
1448 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary) ixcomin2=ixcommin2
1449 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1450 if(neighbor_type(0,1,0,igrid)==neighbor_boundary) ixcomax2=ixcommax2
1451 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1453 else if(idims == 2)
then
1454 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary .or. &
1455 neighbor_type(0,1,0,igrid)==neighbor_boundary)
then
1456 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1457 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1462 ii^d=kr(^d,idims)*(2*iside-3);
1463 if(neighbor_type(ii^d,igrid)/=neighbor_boundary) cycle
1464 if(( {(iside==1.and.idims==^d.and.ixcomin^d<ixcogmin^d+nghostcells)|.or.} ) &
1465 .or.( {(iside==2.and.idims==^d.and.ixcomax^d>ixcogmax^d-nghostcells)|.or. }))
then
1466 {ixbmin^d=merge(ixcogmin^d,ixcomin^d,idims==^d);}
1467 {ixbmax^d=merge(ixcogmax^d,ixcomax^d,idims==^d);}
1468 call bc_phys(iside,idims,time,0.d0,psc(igrid),
ixcog^l,ixb^l)
1474 if(prolongprimitive)
then
1476 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1477 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1482 call interpolation_copy(igrid,ixfi^l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1484 call interpolation_linear(igrid,ixfi^l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1487 if(prolongprimitive)
then
1492 end subroutine bc_prolong
1494 subroutine bc_prolong_stg(igrid,i^D,NeedProlong)
1496 double precision :: dxFi^D,dxCo^D,xFimin^D,xComin^D,invdxCo^D
1497 integer :: igrid,i^D
1498 integer :: ixFi^L,ixCo^L
1499 logical,
dimension(-1:1^D&) :: NeedProlong
1500 logical :: fine_^Lin
1504 if(i^d>-1) fine_min^din=(.not.needprolong(i^dd-kr(^d,^dd)).and.neighbor_type(i^dd-kr(^d,^dd),igrid)/=1)
1505 if(i^d<1) fine_max^din=(.not.needprolong(i^dd+kr(^d,^dd)).and.neighbor_type(i^dd+kr(^d,^dd),igrid)/=1)
1510 dxfi^d=rnode(rpdx^d_,igrid);
1512 invdxco^d=1.d0/dxco^d;
1514 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1515 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1520 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1521 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1523 if(prolongprimitive)
call phys_to_primitive(ixg^ll,ixfi^l,psb(igrid)%w,psb(igrid)%x)
1525 call prolong_2nd_stg(psc(igrid),psb(igrid),ixco^l,ixfi^l,dxco^d,xcomin^d,dxfi^d,xfimin^d,.true.,fine_^lin)
1527 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^l,psb(igrid)%w,psb(igrid)%x)
1530 needprolong(i^d)=.false.
1532 end subroutine bc_prolong_stg
1534 subroutine interpolation_linear(igrid,ixFi^L,dxFi^D,xFimin^D, &
1535 dxCo^D,invdxCo^D,xComin^D)
1537 integer,
intent(in) :: igrid, ixFi^L
1538 double precision,
intent(in) :: dxFi^D, xFimin^D,dxCo^D, invdxCo^D, xComin^D
1540 double precision :: xCo^D, xFi^D, eta^D
1541 double precision :: slopeL, slopeR, slopeC, signC, signR
1542 double precision :: slope(1:nw,ndim)
1544 double precision :: signedfactorhalf^D
1545 integer :: ixCo^D, jxCo^D, hxCo^D, ixFi^D, ix^D, iw, idims, nwmin,nwmax
1550 if(prolongprimitive)
then
1558 {
do ixfi^db = ixfi^lim^db
1561 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1566 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1
1570 xco^db=xcomin^db+(dble(ixco^db)-half)*dxco^db \}
1576 if(slab_uniform)
then
1585 eta^d=(xfi^d-xco^d)*invdxco^d;
1619 ix^d=2*int((ixfi^d+ixmlo^d)/2)-ixmlo^d;
1620 {
if(xfi^d>xco^d)
then
1621 signedfactorhalf^d=0.5d0
1623 signedfactorhalf^d=-0.5d0
1625 eta^d=signedfactorhalf^d*(one-psb(igrid)%dvolume(ixfi^dd) &
1626 /sum(psb(igrid)%dvolume(ix^d:ix^d+1^d%ixFi^dd))) \}
1633 hxco^d=ixco^d-kr(^d,idims)\
1634 jxco^d=ixco^d+kr(^d,idims)\
1637 slopel=psc(igrid)%w(ixco^d,iw)-psc(igrid)%w(hxco^d,iw)
1638 sloper=psc(igrid)%w(jxco^d,iw)-psc(igrid)%w(ixco^d,iw)
1639 slopec=half*(sloper+slopel)
1642 signr=sign(one,sloper)
1643 signc=sign(one,slopec)
1661 slope(iw,idims)=signc*max(zero,min(dabs(slopec), &
1662 signc*slopel,signc*sloper))
1668 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)+&
1669 {(slope(nwmin:nwmax,^d)*eta^d)+}
1673 if(prolongprimitive)
then
1675 call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1678 end subroutine interpolation_linear
1680 subroutine interpolation_copy(igrid, ixFi^L,dxFi^D,xFimin^D, &
1681 dxCo^D,invdxCo^D,xComin^D)
1683 integer,
intent(in) :: igrid, ixFi^L
1684 double precision,
intent(in) :: dxFi^D, xFimin^D,dxCo^D, invdxCo^D, xComin^D
1686 double precision :: xFi^D
1687 integer :: ixCo^D, ixFi^D, nwmin,nwmax
1689 if(prolongprimitive)
then
1697 {
do ixfi^db = ixfi^lim^db
1699 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1703 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1\}
1706 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)
1710 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1712 end subroutine interpolation_copy
1714 subroutine pole_copy(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1716 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,ipole
1717 double precision :: wrecv(ixIR^S,1:nw), wsend(ixIS^S,1:nw)
1719 integer :: iw, iside, iB
1723 iside=int((i^d+3)/2)
1726 select case (typeboundary(iw,ib))
1728 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1730 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1732 call mpistop(
"Pole boundary condition should be symm or asymm")
1737 end subroutine pole_copy
1739 subroutine pole_copy_stg(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,idirs,ipole)
1741 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,idirs,ipole
1743 double precision :: wrecv(ixIR^S,1:nws), wsend(ixIS^S,1:nws)
1744 integer :: iB, iside
1748 iside=int((i^d+3)/2)
1750 select case (typeboundary(iw_mag(idirs),ib))
1752 wrecv(ixr^s,idirs) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1754 wrecv(ixr^s,idirs) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1756 call mpistop(
"Pole boundary condition should be symm or asymm")
1761 end subroutine pole_copy_stg
1763 subroutine pole_buffer(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1765 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,ipole
1766 double precision :: wrecv(ixIR^S,nwhead:nwtail), wsend(ixIS^S,1:nw)
1768 integer :: iw, iside, iB
1772 iside=int((i^d+3)/2)
1775 select case (typeboundary(iw,ib))
1777 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1779 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1781 call mpistop(
"Pole boundary condition should be symm or asymm")
1786 end subroutine pole_buffer