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)
404 double precision,
intent(in) :: time, qdt
405 type(state),
target :: psb(max_blocks)
406 integer,
intent(in) :: nwstart
407 integer,
intent(in) :: nwbc
409 double precision :: time_bcin
410 integer :: nwhead, nwtail
411 integer :: iigrid, igrid, isizes, i^D
412 integer :: isend_buf(npwbuf), ipwbuf, nghostcellsco
413 integer :: flushed_send_c, flushed_send_srl, flushed_send_r, flushed_send_p
415 integer :: ibuf_start, ibuf_next
417 integer,
dimension(1) :: shapes
420 time_bcin=mpi_wtime()
423 nwtail=nwstart+nwbc-1
432 do iigrid=1,igridstail; igrid=igrids(iigrid);
433 if(any(neighbor_type(:^d&,igrid)==neighbor_coarse))
then
467 do iigrid=1,igridstail; igrid=igrids(iigrid);
469 if (skip_direction([ i^d ])) cycle
470 select case (neighbor_type(i^d,igrid))
471 case (neighbor_sibling)
472 call bc_recv_srl(igrid,i^d)
474 call bc_recv_restrict(igrid,i^d)
480 do iigrid=1,igridstail; igrid=igrids(iigrid);
482 if(skip_direction([ i^d ])) cycle
483 select case (neighbor_type(i^d,igrid))
484 case (neighbor_sibling)
485 call bc_send_srl(igrid,i^d)
486 case (neighbor_coarse)
487 call bc_send_restrict(igrid,i^d)
494 if(stagger_grid)
then
502 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
506 do iigrid=1,igridstail; igrid=igrids(iigrid);
508 if(skip_direction([ i^d ])) cycle
509 select case (neighbor_type(i^d,igrid))
510 case(neighbor_sibling)
511 call bc_fill_srl(igrid,i^d)
512 case(neighbor_coarse)
513 call bc_fill_restrict(igrid,i^d)
519 if(stagger_grid)
then
523 do iigrid=1,igridstail; igrid=igrids(iigrid);
525 if (skip_direction([ i^d ])) cycle
526 select case (neighbor_type(i^d,igrid))
527 case (neighbor_sibling)
528 call bc_fill_srl_stg(igrid,i^d)
530 call bc_fill_restrict_stg(igrid,i^d)
546 do iigrid=1,igridstail; igrid=igrids(iigrid);
548 if (skip_direction([ i^d ])) cycle
549 if (neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_recv_prolong(igrid,i^d)
553 do iigrid=1,igridstail; igrid=igrids(iigrid);
555 if (skip_direction([ i^d ])) cycle
556 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_send_prolong(igrid,i^d)
563 if(stagger_grid)
then
569 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
574 do iigrid=1,igridstail; igrid=igrids(iigrid);
576 if (skip_direction([ i^d ])) cycle
577 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_fill_prolong(igrid,i^d)
582 if(stagger_grid)
then
585 do iigrid=1,igridstail; igrid=igrids(iigrid);
587 if (skip_direction([ i^d ])) cycle
588 if(neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_fill_prolong_stg(igrid,i^d)
594 do iigrid=1,igridstail; igrid=igrids(iigrid);
595 call gc_prolong(igrid)
601 if(
associated(usr_prepare_boundary))
then
602 call usr_prepare_boundary(time, qdt)
605 do iigrid=1,igridstail; igrid=igrids(iigrid);
606 if(.not.phyboundblock(igrid)) cycle
607 call fill_boundary_after_gc(igrid)
613 if(
bcphys.and.
associated(phys_boundary_adjust))
then
615 do iigrid=1,igridstail; igrid=igrids(iigrid);
616 if(.not.phyboundblock(igrid)) cycle
617 call phys_boundary_adjust(igrid,psb)
622 time_bc=time_bc+(mpi_wtime()-time_bcin)
627 integer,
intent(in) :: nrequest
628 integer,
intent(inout) :: requests(:)
629 integer,
intent(inout) :: statuses(:,:)
631 if (ghostcell_comm_batched)
then
632 call waitall_range(1,nrequest,requests,statuses)
634 call mpi_waitall(nrequest,requests,statuses,ierrmpi)
638 subroutine waitall_range(ifirst,ilast,requests,statuses)
639 integer,
intent(in) :: ifirst, ilast
640 integer,
intent(inout) :: requests(:)
641 integer,
intent(inout) :: statuses(:,:)
643 integer :: irequest,nwait
645 do irequest=ifirst,ilast,ghostcell_comm_batch_size
646 nwait=min(ghostcell_comm_batch_size,ilast-irequest+1)
647 call mpi_waitall(nwait,requests(irequest:irequest+nwait-1),&
648 statuses(:,irequest:irequest+nwait-1),ierrmpi)
650 end subroutine waitall_range
652 subroutine waitall_pending(nrequest,nwaited,requests,statuses)
653 integer,
intent(in) :: nrequest
654 integer,
intent(inout) :: nwaited
655 integer,
intent(inout) :: requests(:)
656 integer,
intent(inout) :: statuses(:,:)
658 if (nrequest>nwaited)
then
659 if (ghostcell_comm_batched)
then
660 call waitall_range(nwaited+1,nrequest,requests,statuses)
662 call mpi_waitall(nrequest-nwaited,requests(nwaited+1:nrequest),&
663 statuses(:,nwaited+1:nrequest),ierrmpi)
667 end subroutine waitall_pending
669 subroutine wait_send_batch(nrequest,nwaited,requests,statuses)
670 integer,
intent(in) :: nrequest
671 integer,
intent(inout) :: nwaited
672 integer,
intent(inout) :: requests(:)
673 integer,
intent(inout) :: statuses(:,:)
675 if (ghostcell_comm_batched .and. &
676 nrequest-nwaited >= ghostcell_comm_batch_size)
then
677 call waitall_range(nwaited+1,nrequest,requests,statuses)
680 end subroutine wait_send_batch
682 logical function skip_direction(dir)
683 integer,
intent(in) :: dir(^ND)
685 if (all(dir == 0))
then
686 skip_direction = .true.
688 skip_direction = .false.
690 end function skip_direction
693 subroutine fill_boundary_after_gc(igrid)
695 integer,
intent(in) :: igrid
697 integer :: idims,iside,i^D,k^L,ixB^L,ixO^L
698 logical :: has_eos_bc
704 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
711 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,igrid)==1)
712 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,igrid)==1)}
714 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,0,igrid)==1)
715 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,0,igrid)==1)
716 kmin3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0,-1,igrid)==1)
717 kmax3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0, 1,igrid)==1)}
718 ixbmin^d=ixglo^d+kmin^d*nghostcells;
719 ixbmax^d=ixghi^d-kmax^d*nghostcells;
721 i^d=kr(^d,idims)*(2*iside-3);
722 if (aperiodb(idims))
then
723 if (neighbor_type(i^d,igrid) /= neighbor_boundary .and. &
724 .not. psb(igrid)%is_physical_boundary(2*idims-2+iside)) cycle
726 if (neighbor_type(i^d,igrid) /= neighbor_boundary) cycle
735 call bc_phys(iside,idims,time,qdt,psb(igrid),ixg^ll,ixb^l)
746 ixomin^dd=ixbmax^d+1-nghostcells^d%ixOmin^dd=ixbmin^dd;
750 ixomax^dd=ixbmin^d-1+nghostcells^d%ixOmax^dd=ixbmax^dd;
758 end subroutine fill_boundary_after_gc
761 subroutine bc_recv_srl(igrid,i^D)
762 integer,
intent(in) :: igrid,i^D
764 integer :: ipe_neighbor
766 ipe_neighbor=neighbor(2,i^d,igrid)
767 if (ipe_neighbor/=mype)
then
769 itag=(3**^nd+4**^nd)*(igrid-1)+{(i^d+1)*3**(^d-1)+}
772 if(stagger_grid)
then
780 end subroutine bc_recv_srl
783 subroutine bc_recv_restrict(igrid,i^D)
784 integer,
intent(in) :: igrid,i^D
786 integer :: ic^D,inc^D,ipe_neighbor
788 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
789 inc^db=2*i^db+ic^db\}
790 ipe_neighbor=neighbor_child(2,inc^d,igrid)
791 if (ipe_neighbor/=mype)
then
793 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
794 call mpi_irecv(psb(igrid)%w,1,
type_recv_r(inc^d), &
796 if(stagger_grid)
then
799 mpi_double_precision,ipe_neighbor,itag, &
806 end subroutine bc_recv_restrict
809 subroutine bc_send_srl(igrid,i^D)
810 integer,
intent(in) :: igrid,i^D
812 integer :: n_i^D,ipole,idir,ineighbor,ipe_neighbor,ixS^L
814 ipe_neighbor=neighbor(2,i^d,igrid)
815 if(ipe_neighbor/=mype)
then
816 ineighbor=neighbor(1,i^d,igrid)
817 ipole=neighbor_pole(i^d,igrid)
821 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
825 if(stagger_grid)
then
832 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
845 n_i^d=i^d^d%n_i^dd=-i^dd;\}
847 if (isend_buf(ipwbuf)/=0)
then
850 deallocate(pwbuf(ipwbuf)%w)
852 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
853 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
856 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
857 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
858 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
861 ipwbuf=1+modulo(ipwbuf,
npwbuf)
862 if(stagger_grid)
then
869 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
881 end subroutine bc_send_srl
884 subroutine bc_send_restrict(igrid,i^D)
885 integer,
intent(in) :: igrid,i^D
887 integer :: ic^D,n_inc^D,ipole,idir,ineighbor,ipe_neighbor,ixS^L
889 ipe_neighbor=neighbor(2,i^d,igrid)
890 if(ipe_neighbor/=mype)
then
891 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
892 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
893 ineighbor=neighbor(1,i^d,igrid)
894 ipole=neighbor_pole(i^d,igrid)
898 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
902 if(stagger_grid)
then
909 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
914 mpi_double_precision,ipe_neighbor,itag, &
923 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
925 if(isend_buf(ipwbuf)/=0)
then
928 deallocate(pwbuf(ipwbuf)%w)
930 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
931 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psc(igrid)%w,
ixcog^l,ixs^l,ipole)
934 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
935 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
936 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
939 ipwbuf=1+modulo(ipwbuf,
npwbuf)
940 if(stagger_grid)
then
947 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
952 mpi_double_precision,ipe_neighbor,itag, &
960 end subroutine bc_send_restrict
963 subroutine bc_fill_srl(igrid,i^D)
964 integer,
intent(in) :: igrid,i^D
966 integer :: ineighbor,ipe_neighbor,ipole,ixS^L,ixR^L,n_i^D,idir
968 ipe_neighbor=neighbor(2,i^d,igrid)
969 if(ipe_neighbor==mype)
then
970 ineighbor=neighbor(1,i^d,igrid)
971 ipole=neighbor_pole(i^d,igrid)
976 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
977 psb(igrid)%w(ixs^s,nwhead:nwtail)
978 if(stagger_grid)
then
982 psb(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
989 n_i^d=i^d^d%n_i^dd=-i^dd;\}
992 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
993 if(stagger_grid)
then
997 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^l,psb(igrid)%ws,ixgs^ll,ixs^l,idir,ipole)
1003 end subroutine bc_fill_srl
1006 subroutine bc_fill_restrict(igrid,i^D)
1007 integer,
intent(in) :: igrid,i^D
1009 integer :: ic^D,n_inc^D,ixS^L,ixR^L,ipe_neighbor,ineighbor,ipole,idir
1011 ipe_neighbor=neighbor(2,i^d,igrid)
1012 if(ipe_neighbor==mype)
then
1013 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1014 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1015 ineighbor=neighbor(1,i^d,igrid)
1016 ipole=neighbor_pole(i^d,igrid)
1018 n_inc^d=-2*i^d+ic^d;
1021 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
1022 psc(igrid)%w(ixs^s,nwhead:nwtail)
1023 if(stagger_grid)
then
1027 psb(ineighbor)%ws(ixr^s,idir)=psc(igrid)%ws(ixs^s,idir)
1034 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
1037 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^l,psc(igrid)%w,
ixcog^l,ixs^l,ipole)
1038 if(stagger_grid)
then
1043 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^l,psc(igrid)%ws,
ixcogs^l,ixs^l,idir,ipole)
1049 end subroutine bc_fill_restrict
1052 subroutine bc_fill_srl_stg(igrid,i^D)
1053 integer,
intent(in) :: igrid,i^D
1055 integer :: ixS^L,ixR^L,n_i^D,idir,ineighbor,ipe_neighbor,ipole
1057 ipe_neighbor=neighbor(2,i^d,igrid)
1058 if(ipe_neighbor/=mype)
then
1059 ineighbor=neighbor(1,i^d,igrid)
1060 ipole=neighbor_pole(i^d,igrid)
1072 shape=shape(psb(igrid)%ws(ixs^s,idir)))
1078 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1086 shape=shape(psb(igrid)%ws(ixs^s,idir)))
1088 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^l,pole_buf%ws,ixgs^ll,ixs^l,idir,ipole)
1093 end subroutine bc_fill_srl_stg
1096 subroutine bc_fill_restrict_stg(igrid,i^D)
1097 integer,
intent(in) :: igrid,i^D
1099 integer :: ipole,ic^D,inc^D,ineighbor,ipe_neighbor,ixS^L,ixR^L,n_i^D,idir
1101 ipole=neighbor_pole(i^d,igrid)
1104 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1105 inc^db=2*i^db+ic^db\}
1106 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1107 if(ipe_neighbor/=mype)
then
1108 ineighbor=neighbor_child(1,inc^d,igrid)
1115 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1121 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1122 inc^db=2*i^db+ic^db\}
1123 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1124 if(ipe_neighbor/=mype)
then
1125 ineighbor=neighbor_child(1,inc^d,igrid)
1128 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1138 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1139 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^
l,pole_buf%ws,ixgs^ll,ixr^
l,idir,ipole)
1146 end subroutine bc_fill_restrict_stg
1149 subroutine bc_recv_prolong(igrid,i^D)
1150 integer,
intent(in) :: igrid,i^D
1152 integer :: ic^D,ipe_neighbor,inc^D
1154 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1155 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1157 ipe_neighbor=neighbor(2,i^d,igrid)
1158 if (ipe_neighbor/=mype)
then
1161 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
1162 call mpi_irecv(psc(igrid)%w,1,
type_recv_p(inc^d), &
1164 if(stagger_grid)
then
1167 mpi_double_precision,ipe_neighbor,itag,&
1173 end subroutine bc_recv_prolong
1176 subroutine bc_send_prolong(igrid,i^D)
1177 integer,
intent(in) :: igrid,i^D
1179 integer :: ic^D,inc^D,n_i^D,n_inc^D,ineighbor,ipe_neighbor,ixS^L,ipole,idir
1181 ipole=neighbor_pole(i^d,igrid)
1183 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1184 inc^db=2*i^db+ic^db\}
1185 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1186 if(ipe_neighbor/=mype)
then
1187 ineighbor=neighbor_child(1,inc^d,igrid)
1192 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1193 call mpi_isend(psb(igrid)%w,1,
type_send_p(inc^d), &
1196 if(stagger_grid)
then
1203 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1204 ibuf_start=ibuf_next
1208 mpi_double_precision,ipe_neighbor,itag, &
1217 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1219 if(isend_buf(ipwbuf)/=0)
then
1222 deallocate(pwbuf(ipwbuf)%w)
1224 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
1225 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
1228 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1229 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
1230 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
1233 ipwbuf=1+modulo(ipwbuf,
npwbuf)
1234 if(stagger_grid)
then
1241 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1242 ibuf_start=ibuf_next
1246 mpi_double_precision,ipe_neighbor,itag, &
1255 end subroutine bc_send_prolong
1258 subroutine bc_fill_prolong(igrid,i^D)
1259 integer,
intent(in) :: igrid,i^D
1261 integer :: ipe_neighbor,ineighbor,ixS^L,ixR^L,ic^D,inc^D,n_i^D,n_inc^D,ipole,idir
1263 ipole=neighbor_pole(i^d,igrid)
1266 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1267 inc^db=2*i^db+ic^db\}
1268 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1269 if(ipe_neighbor==mype)
then
1271 ineighbor=neighbor_child(1,inc^d,igrid)
1275 psc(ineighbor)%w(ixr^s,nwhead:nwtail) &
1276 =psb(igrid)%w(ixs^s,nwhead:nwtail)
1277 if(stagger_grid)
then
1281 psc(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
1287 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1288 inc^db=2*i^db+ic^db\}
1289 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1290 if(ipe_neighbor==mype)
then
1292 ineighbor=neighbor_child(1,inc^d,igrid)
1295 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1298 call pole_copy(psc(ineighbor)%w,
ixcog^
l,ixr^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
1299 if(stagger_grid)
then
1303 call pole_copy_stg(psc(ineighbor)%ws,
ixcogs^
l,ixr^
l,psb(igrid)%ws,ixgs^ll,ixs^
l,idir,ipole)
1309 end subroutine bc_fill_prolong
1311 subroutine gc_prolong(igrid)
1312 integer,
intent(in) :: igrid
1314 integer :: i^D,idims,iside
1315 logical,
dimension(-1:1^D&) :: NeedProlong
1319 if (skip_direction([ i^d ])) cycle
1320 if (neighbor_type(i^d,igrid)==neighbor_coarse)
then
1321 call bc_prolong(igrid,i^d)
1322 needprolong(i^d)=.true.
1325 if(stagger_grid)
then
1336 if (needprolong(i^dd))
call bc_prolong_stg(igrid,i^dd,needprolong)
1347 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1353 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1359 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1365 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1368 end subroutine gc_prolong
1371 subroutine bc_fill_prolong_stg(igrid,i^D)
1372 integer,
intent(in) :: igrid,i^D
1374 integer :: ipe_neighbor,ineighbor,ipole,ixR^L,ic^D,inc^D,n_inc^D,idir
1376 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1377 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1379 ipe_neighbor=neighbor(2,i^d,igrid)
1380 if(ipe_neighbor/=mype)
then
1381 ineighbor=neighbor(1,i^d,igrid)
1382 ipole=neighbor_pole(i^d,igrid)
1391 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1398 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
1406 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1407 call pole_copy_stg(psc(igrid)%ws,
ixcogs^l,ixr^l,pole_buf%ws,ixgs^ll,ixr^l,idir,ipole)
1413 end subroutine bc_fill_prolong_stg
1416 subroutine bc_prolong(igrid,i^D)
1420 double precision :: dxFi^D, dxCo^D, xFimin^D, xComin^D, invdxCo^D
1421 integer :: i^D,igrid
1422 integer :: ixFi^L,ixCo^L,ii^D, idims,iside,ixB^L
1425 dxfi^d=rnode(rpdx^d_,igrid);
1427 invdxco^d=1.d0/dxco^d;
1433 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1434 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1436 if(phyboundblock(igrid).and.
bcphys)
then
1439 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1440 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1444 if(neighbor_type(-1,0,0,igrid)==neighbor_boundary .or. &
1445 neighbor_type(1,0,0,igrid)==neighbor_boundary)
then
1446 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary) ixcomin2=ixcommin2
1447 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1448 if(neighbor_type(0,1,0,igrid)==neighbor_boundary) ixcomax2=ixcommax2
1449 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1451 else if(idims == 2)
then
1452 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary .or. &
1453 neighbor_type(0,1,0,igrid)==neighbor_boundary)
then
1454 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1455 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1460 ii^d=kr(^d,idims)*(2*iside-3);
1461 if(neighbor_type(ii^d,igrid)/=neighbor_boundary) cycle
1462 if(( {(iside==1.and.idims==^d.and.ixcomin^d<ixcogmin^d+nghostcells)|.or.} ) &
1463 .or.( {(iside==2.and.idims==^d.and.ixcomax^d>ixcogmax^d-nghostcells)|.or. }))
then
1464 {ixbmin^d=merge(ixcogmin^d,ixcomin^d,idims==^d);}
1465 {ixbmax^d=merge(ixcogmax^d,ixcomax^d,idims==^d);}
1466 call bc_phys(iside,idims,time,0.d0,psc(igrid),
ixcog^l,ixb^l)
1472 if(prolongprimitive)
then
1474 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1475 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1480 call interpolation_copy(igrid,ixfi^l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1482 call interpolation_linear(igrid,ixfi^l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1485 if(prolongprimitive)
then
1490 end subroutine bc_prolong
1492 subroutine bc_prolong_stg(igrid,i^D,NeedProlong)
1494 double precision :: dxFi^D,dxCo^D,xFimin^D,xComin^D,invdxCo^D
1495 integer :: igrid,i^D
1496 integer :: ixFi^L,ixCo^L
1497 logical,
dimension(-1:1^D&) :: NeedProlong
1498 logical :: fine_^Lin
1502 if(i^d>-1) fine_min^din=(.not.needprolong(i^dd-kr(^d,^dd)).and.neighbor_type(i^dd-kr(^d,^dd),igrid)/=1)
1503 if(i^d<1) fine_max^din=(.not.needprolong(i^dd+kr(^d,^dd)).and.neighbor_type(i^dd+kr(^d,^dd),igrid)/=1)
1508 dxfi^d=rnode(rpdx^d_,igrid);
1510 invdxco^d=1.d0/dxco^d;
1512 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1513 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1518 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1519 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1521 if(prolongprimitive)
call phys_to_primitive(ixg^ll,ixfi^l,psb(igrid)%w,psb(igrid)%x)
1523 call prolong_2nd_stg(psc(igrid),psb(igrid),ixco^l,ixfi^l,dxco^d,xcomin^d,dxfi^d,xfimin^d,.true.,fine_^lin)
1525 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^l,psb(igrid)%w,psb(igrid)%x)
1528 needprolong(i^d)=.false.
1530 end subroutine bc_prolong_stg
1532 subroutine interpolation_linear(igrid,ixFi^L,dxFi^D,xFimin^D, &
1533 dxCo^D,invdxCo^D,xComin^D)
1535 integer,
intent(in) :: igrid, ixFi^L
1536 double precision,
intent(in) :: dxFi^D, xFimin^D,dxCo^D, invdxCo^D, xComin^D
1538 double precision :: xCo^D, xFi^D, eta^D
1539 double precision :: slopeL, slopeR, slopeC, signC, signR
1540 double precision :: slope(1:nw,ndim)
1542 double precision :: signedfactorhalf^D
1543 integer :: ixCo^D, jxCo^D, hxCo^D, ixFi^D, ix^D, iw, idims, nwmin,nwmax
1548 if(prolongprimitive)
then
1556 {
do ixfi^db = ixfi^lim^db
1559 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1564 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1
1568 xco^db=xcomin^db+(dble(ixco^db)-half)*dxco^db \}
1574 if(slab_uniform)
then
1583 eta^d=(xfi^d-xco^d)*invdxco^d;
1617 ix^d=2*int((ixfi^d+ixmlo^d)/2)-ixmlo^d;
1618 {
if(xfi^d>xco^d)
then
1619 signedfactorhalf^d=0.5d0
1621 signedfactorhalf^d=-0.5d0
1623 eta^d=signedfactorhalf^d*(one-psb(igrid)%dvolume(ixfi^dd) &
1624 /sum(psb(igrid)%dvolume(ix^d:ix^d+1^d%ixFi^dd))) \}
1631 hxco^d=ixco^d-kr(^d,idims)\
1632 jxco^d=ixco^d+kr(^d,idims)\
1635 slopel=psc(igrid)%w(ixco^d,iw)-psc(igrid)%w(hxco^d,iw)
1636 sloper=psc(igrid)%w(jxco^d,iw)-psc(igrid)%w(ixco^d,iw)
1637 slopec=half*(sloper+slopel)
1640 signr=sign(one,sloper)
1641 signc=sign(one,slopec)
1659 slope(iw,idims)=signc*max(zero,min(dabs(slopec), &
1660 signc*slopel,signc*sloper))
1666 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)+&
1667 {(slope(nwmin:nwmax,^d)*eta^d)+}
1671 if(prolongprimitive)
then
1673 call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1676 end subroutine interpolation_linear
1678 subroutine interpolation_copy(igrid, ixFi^L,dxFi^D,xFimin^D, &
1679 dxCo^D,invdxCo^D,xComin^D)
1681 integer,
intent(in) :: igrid, ixFi^L
1682 double precision,
intent(in) :: dxFi^D, xFimin^D,dxCo^D, invdxCo^D, xComin^D
1684 double precision :: xFi^D
1685 integer :: ixCo^D, ixFi^D, nwmin,nwmax
1687 if(prolongprimitive)
then
1695 {
do ixfi^db = ixfi^lim^db
1697 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1701 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1\}
1704 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)
1708 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1710 end subroutine interpolation_copy
1712 subroutine pole_copy(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1714 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,ipole
1715 double precision :: wrecv(ixIR^S,1:nw), wsend(ixIS^S,1:nw)
1717 integer :: iw, iside, iB
1721 iside=int((i^d+3)/2)
1724 select case (typeboundary(iw,ib))
1726 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1728 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1730 call mpistop(
"Pole boundary condition should be symm or asymm")
1735 end subroutine pole_copy
1737 subroutine pole_copy_stg(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,idirs,ipole)
1739 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,idirs,ipole
1741 double precision :: wrecv(ixIR^S,1:nws), wsend(ixIS^S,1:nws)
1742 integer :: iB, iside
1746 iside=int((i^d+3)/2)
1748 select case (typeboundary(iw_mag(idirs),ib))
1750 wrecv(ixr^s,idirs) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1752 wrecv(ixr^s,idirs) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1754 call mpistop(
"Pole boundary condition should be symm or asymm")
1759 end subroutine pole_copy_stg
1761 subroutine pole_buffer(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1763 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,ipole
1764 double precision :: wrecv(ixIR^S,nwhead:nwtail), wsend(ixIS^S,1:nw)
1766 integer :: iw, iside, iB
1770 iside=int((i^d+3)/2)
1773 select case (typeboundary(iw,ib))
1775 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1777 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1779 call mpistop(
"Pole boundary condition should be symm or asymm")
1784 end subroutine pole_buffer