132 integer :: nghostcellsCo, interpolation_order
133 integer :: nx^D, nxCo^D, ixG^L, i^D, idir
136 ixm^l=ixg^l^lsubnghostcells;
140 ixcogsmax^d=ixcogmax^d;
144 nx^d=ixmmax^d-ixmmin^d+1;
148 interpolation_order=1
150 interpolation_order=2
154 if (nghostcellsco+interpolation_order-1>
nghostcells)
then
155 call mpistop(
"interpolation order for prolongation in getbc too high")
161 ixs_srl_min^d(-1)=ixmmin^d
162 ixs_srl_min^d( 0)=ixmmin^d
165 ixs_srl_max^d( 0)=ixmmax^d
166 ixs_srl_max^d( 1)=ixmmax^d
169 ixr_srl_min^d( 0)=ixmmin^d
170 ixr_srl_min^d( 1)=ixmmax^d+1
172 ixr_srl_max^d( 0)=ixmmax^d
173 ixr_srl_max^d( 1)=ixgmax^d
175 ixs_r_min^d(-1)=ixcommin^d
176 ixs_r_min^d( 0)=ixcommin^d
179 ixs_r_max^d( 0)=ixcommax^d
180 ixs_r_max^d( 1)=ixcommax^d
183 ixr_r_min^d(1)=ixmmin^d
184 ixr_r_min^d(2)=ixmmin^d+nxco^d
185 ixr_r_min^d(3)=ixmmax^d+1
187 ixr_r_max^d(1)=ixmmin^d-1+nxco^d
188 ixr_r_max^d(2)=ixmmax^d
189 ixr_r_max^d(3)=ixgmax^d
191 ixs_p_min^d(0)=ixmmin^d-(interpolation_order-1)
192 ixs_p_min^d(1)=ixmmin^d-(interpolation_order-1)
193 ixs_p_min^d(2)=ixmmin^d+nxco^d-nghostcellsco-(interpolation_order-1)
194 ixs_p_min^d(3)=ixmmax^d+1-nghostcellsco-(interpolation_order-1)
195 ixs_p_max^d(0)=ixmmin^d-1+nghostcellsco+(interpolation_order-1)
196 ixs_p_max^d(1)=ixmmin^d-1+nxco^d+nghostcellsco+(interpolation_order-1)
197 ixs_p_max^d(2)=ixmmax^d+(interpolation_order-1)
198 ixs_p_max^d(3)=ixmmax^d+(interpolation_order-1)
200 ixr_p_min^d(0)=ixcommin^d-nghostcellsco-(interpolation_order-1)
201 ixr_p_min^d(1)=ixcommin^d-(interpolation_order-1)
202 ixr_p_min^d(2)=ixcommin^d-nghostcellsco-(interpolation_order-1)
203 ixr_p_min^d(3)=ixcommax^d+1-(interpolation_order-1)
205 ixr_p_max^d(1)=ixcommax^d+nghostcellsco+(interpolation_order-1)
206 ixr_p_max^d(2)=ixcommax^d+(interpolation_order-1)
207 ixr_p_max^d(3)=ixcommax^d+nghostcellsco+(interpolation_order-1)
212 allocate(pole_buf%ws(ixgs^t,nws))
215 { ixs_srl_stg_min^d(idir,-1)=ixmmin^d-
kr(idir,^d)
217 ixs_srl_stg_min^d(idir,0) =ixmmin^d-
kr(idir,^d)
218 ixs_srl_stg_max^d(idir,0) =ixmmax^d
219 ixs_srl_stg_min^d(idir,1) =ixmmax^d-
nghostcells+1-
kr(idir,^d)
220 ixs_srl_stg_max^d(idir,1) =ixmmax^d
222 ixr_srl_stg_min^d(idir,-1)=1-
kr(idir,^d)
224 ixr_srl_stg_min^d(idir,0) =ixmmin^d-
kr(idir,^d)
225 ixr_srl_stg_max^d(idir,0) =ixmmax^d
226 ixr_srl_stg_min^d(idir,1) =ixmmax^d+1-
kr(idir,^d)
227 ixr_srl_stg_max^d(idir,1) =ixgmax^d
229 ixs_r_stg_min^d(idir,-1)=ixcommin^d-
kr(idir,^d)
231 ixs_r_stg_min^d(idir,0) =ixcommin^d-
kr(idir,^d)
232 ixs_r_stg_max^d(idir,0) =ixcommax^d
233 ixs_r_stg_min^d(idir,1) =ixcommax^d+1-
nghostcells-
kr(idir,^d)
234 ixs_r_stg_max^d(idir,1) =ixcommax^d
236 ixr_r_stg_min^d(idir,0)=1-
kr(idir,^d)
238 ixr_r_stg_min^d(idir,1)=ixmmin^d-
kr(idir,^d)
239 ixr_r_stg_max^d(idir,1)=ixmmin^d-1+nxco^d
240 ixr_r_stg_min^d(idir,2)=ixmmin^d+nxco^d-
kr(idir,^d)
241 ixr_r_stg_max^d(idir,2)=ixmmax^d
242 ixr_r_stg_min^d(idir,3)=ixmmax^d+1-
kr(idir,^d)
243 ixr_r_stg_max^d(idir,3)=ixgmax^d
248 ixs_p_stg_min^d(idir,0)=ixmmin^d-1
249 ixs_p_stg_max^d(idir,0)=ixmmin^d-1+nghostcellsco
250 ixs_p_stg_min^d(idir,1)=ixmmin^d-1
251 ixs_p_stg_max^d(idir,1)=ixmmin^d-1+nxco^d+nghostcellsco
252 ixs_p_stg_min^d(idir,2)=ixmmax^d-nxco^d-nghostcellsco
253 ixs_p_stg_max^d(idir,2)=ixmmax^d
254 ixs_p_stg_min^d(idir,3)=ixmmax^d-nghostcellsco
255 ixs_p_stg_max^d(idir,3)=ixmmax^d
257 ixr_p_stg_min^d(idir,0)=ixcommin^d-1-nghostcellsco
258 ixr_p_stg_max^d(idir,0)=ixcommin^d-1
259 ixr_p_stg_min^d(idir,1)=ixcommin^d-1
260 ixr_p_stg_max^d(idir,1)=ixcommax^d+nghostcellsco
261 ixr_p_stg_min^d(idir,2)=ixcommin^d-1-nghostcellsco
262 ixr_p_stg_max^d(idir,2)=ixcommax^d
263 ixr_p_stg_min^d(idir,3)=ixcommax^d+1-1
264 ixr_p_stg_max^d(idir,3)=ixcommax^d+nghostcellsco
269 ixs_p_stg_min^d(idir,0)=ixmmin^d
270 ixs_p_stg_max^d(idir,0)=ixmmin^d-1+nghostcellsco+(interpolation_order-1)
271 ixs_p_stg_min^d(idir,1)=ixmmin^d
272 ixs_p_stg_max^d(idir,1)=ixmmin^d-1+nxco^d+nghostcellsco+(interpolation_order-1)
273 ixs_p_stg_min^d(idir,2)=ixmmax^d+1-nxco^d-nghostcellsco-(interpolation_order-1)
274 ixs_p_stg_max^d(idir,2)=ixmmax^d
275 ixs_p_stg_min^d(idir,3)=ixmmax^d+1-nghostcellsco-(interpolation_order-1)
276 ixs_p_stg_max^d(idir,3)=ixmmax^d
278 ixr_p_stg_min^d(idir,0)=ixcommin^d-nghostcellsco-(interpolation_order-1)
279 ixr_p_stg_max^d(idir,0)=ixcommin^d-1
280 ixr_p_stg_min^d(idir,1)=ixcommin^d
281 ixr_p_stg_max^d(idir,1)=ixcommax^d+nghostcellsco+(interpolation_order-1)
282 ixr_p_stg_min^d(idir,2)=ixcommin^d-nghostcellsco-(interpolation_order-1)
283 ixr_p_stg_max^d(idir,2)=ixcommax^d
284 ixr_p_stg_min^d(idir,3)=ixcommax^d+1
285 ixr_p_stg_max^d(idir,3)=ixcommax^d+nghostcellsco+(interpolation_order-1)
294 sizes_srl_send_stg(idir,i^d)={(ixs_srl_stg_max^d(idir,i^d)-ixs_srl_stg_min^d(idir,i^d)+1)|*}
295 sizes_srl_recv_stg(idir,i^d)={(ixr_srl_stg_max^d(idir,i^d)-ixr_srl_stg_min^d(idir,i^d)+1)|*}
296 sizes_r_send_stg(idir,i^d)={(ixs_r_stg_max^d(idir,i^d)-ixs_r_stg_min^d(idir,i^d)+1)|*}
306 sizes_r_recv_stg(idir,i^d)={(ixr_r_stg_max^d(idir,i^d)-ixr_r_stg_min^d(idir,i^d)+1)|*}
307 sizes_p_send_stg(idir,i^d)={(ixs_p_stg_max^d(idir,i^d)-ixs_p_stg_min^d(idir,i^d)+1)|*}
308 sizes_p_recv_stg(idir,i^d)={(ixr_p_stg_max^d(idir,i^d)-ixr_p_stg_min^d(idir,i^d)+1)|*}
361 subroutine getbc(time,qdt,psb,nwstart,nwbc)
369 double precision,
intent(in) :: time, qdt
370 type(state),
target :: psb(max_blocks)
371 integer,
intent(in) :: nwstart
372 integer,
intent(in) :: nwbc
374 double precision :: time_bcin
375 integer :: nwhead, nwtail
376 integer :: iigrid, igrid, isizes, i^D
377 integer :: isend_buf(npwbuf), ipwbuf, nghostcellsco
378 integer :: flushed_send_c, flushed_send_srl, flushed_send_r, flushed_send_p
380 integer :: ibuf_start, ibuf_next
382 integer,
dimension(1) :: shapes
385 time_bcin=mpi_wtime()
388 nwtail=nwstart+nwbc-1
397 do iigrid=1,igridstail; igrid=igrids(iigrid);
398 if(any(neighbor_type(:^d&,igrid)==neighbor_coarse))
then
432 do iigrid=1,igridstail; igrid=igrids(iigrid);
434 if (skip_direction([ i^d ])) cycle
435 select case (neighbor_type(i^d,igrid))
436 case (neighbor_sibling)
437 call bc_recv_srl(igrid,i^d)
439 call bc_recv_restrict(igrid,i^d)
445 do iigrid=1,igridstail; igrid=igrids(iigrid);
447 if(skip_direction([ i^d ])) cycle
448 select case (neighbor_type(i^d,igrid))
449 case (neighbor_sibling)
450 call bc_send_srl(igrid,i^d)
451 case (neighbor_coarse)
452 call bc_send_restrict(igrid,i^d)
459 if(stagger_grid)
then
467 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
471 do iigrid=1,igridstail; igrid=igrids(iigrid);
473 if(skip_direction([ i^d ])) cycle
474 select case (neighbor_type(i^d,igrid))
475 case(neighbor_sibling)
476 call bc_fill_srl(igrid,i^d)
477 case(neighbor_coarse)
478 call bc_fill_restrict(igrid,i^d)
484 if(stagger_grid)
then
488 do iigrid=1,igridstail; igrid=igrids(iigrid);
490 if (skip_direction([ i^d ])) cycle
491 select case (neighbor_type(i^d,igrid))
492 case (neighbor_sibling)
493 call bc_fill_srl_stg(igrid,i^d)
495 call bc_fill_restrict_stg(igrid,i^d)
511 do iigrid=1,igridstail; igrid=igrids(iigrid);
513 if (skip_direction([ i^d ])) cycle
514 if (neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_recv_prolong(igrid,i^d)
518 do iigrid=1,igridstail; igrid=igrids(iigrid);
520 if (skip_direction([ i^d ])) cycle
521 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_send_prolong(igrid,i^d)
528 if(stagger_grid)
then
534 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
539 do iigrid=1,igridstail; igrid=igrids(iigrid);
541 if (skip_direction([ i^d ])) cycle
542 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_fill_prolong(igrid,i^d)
547 if(stagger_grid)
then
550 do iigrid=1,igridstail; igrid=igrids(iigrid);
552 if (skip_direction([ i^d ])) cycle
553 if(neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_fill_prolong_stg(igrid,i^d)
559 do iigrid=1,igridstail; igrid=igrids(iigrid);
560 call gc_prolong(igrid)
566 if(
associated(usr_prepare_boundary))
then
567 call usr_prepare_boundary(time, qdt)
570 do iigrid=1,igridstail; igrid=igrids(iigrid);
571 if(.not.phyboundblock(igrid)) cycle
572 call fill_boundary_after_gc(igrid)
578 if(
bcphys.and.
associated(phys_boundary_adjust))
then
580 do iigrid=1,igridstail; igrid=igrids(iigrid);
581 if(.not.phyboundblock(igrid)) cycle
582 call phys_boundary_adjust(igrid,psb)
587 time_bc=time_bc+(mpi_wtime()-time_bcin)
592 integer,
intent(in) :: nrequest
593 integer,
intent(inout) :: requests(:)
594 integer,
intent(inout) :: statuses(:,:)
596 if (ghostcell_comm_batched)
then
597 call waitall_range(1,nrequest,requests,statuses)
599 call mpi_waitall(nrequest,requests,statuses,ierrmpi)
603 subroutine waitall_range(ifirst,ilast,requests,statuses)
604 integer,
intent(in) :: ifirst, ilast
605 integer,
intent(inout) :: requests(:)
606 integer,
intent(inout) :: statuses(:,:)
608 integer :: irequest,nwait
610 do irequest=ifirst,ilast,ghostcell_comm_batch_size
611 nwait=min(ghostcell_comm_batch_size,ilast-irequest+1)
612 call mpi_waitall(nwait,requests(irequest:irequest+nwait-1),&
613 statuses(:,irequest:irequest+nwait-1),ierrmpi)
615 end subroutine waitall_range
617 subroutine waitall_pending(nrequest,nwaited,requests,statuses)
618 integer,
intent(in) :: nrequest
619 integer,
intent(inout) :: nwaited
620 integer,
intent(inout) :: requests(:)
621 integer,
intent(inout) :: statuses(:,:)
623 if (nrequest>nwaited)
then
624 if (ghostcell_comm_batched)
then
625 call waitall_range(nwaited+1,nrequest,requests,statuses)
627 call mpi_waitall(nrequest-nwaited,requests(nwaited+1:nrequest),&
628 statuses(:,nwaited+1:nrequest),ierrmpi)
632 end subroutine waitall_pending
634 subroutine wait_send_batch(nrequest,nwaited,requests,statuses)
635 integer,
intent(in) :: nrequest
636 integer,
intent(inout) :: nwaited
637 integer,
intent(inout) :: requests(:)
638 integer,
intent(inout) :: statuses(:,:)
640 if (ghostcell_comm_batched .and. &
641 nrequest-nwaited >= ghostcell_comm_batch_size)
then
642 call waitall_range(nwaited+1,nrequest,requests,statuses)
645 end subroutine wait_send_batch
647 logical function skip_direction(dir)
648 integer,
intent(in) :: dir(^ND)
650 if (all(dir == 0))
then
651 skip_direction = .true.
653 skip_direction = .false.
655 end function skip_direction
658 subroutine fill_boundary_after_gc(igrid)
660 integer,
intent(in) :: igrid
662 integer :: idims,iside,i^D,k^L,ixB^L
665 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
672 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,igrid)==1)
673 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,igrid)==1)}
675 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,0,igrid)==1)
676 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,0,igrid)==1)
677 kmin3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0,-1,igrid)==1)
678 kmax3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0, 1,igrid)==1)}
679 ixbmin^d=ixglo^d+kmin^d*nghostcells;
680 ixbmax^d=ixghi^d-kmax^d*nghostcells;
682 i^d=kr(^d,idims)*(2*iside-3);
683 if (aperiodb(idims))
then
684 if (neighbor_type(i^d,igrid) /= neighbor_boundary .and. &
685 .not. psb(igrid)%is_physical_boundary(2*idims-2+iside)) cycle
687 if (neighbor_type(i^d,igrid) /= neighbor_boundary) cycle
693 call bc_phys(iside,idims,time,qdt,psb(igrid),ixg^ll,ixb^l)
697 end subroutine fill_boundary_after_gc
700 subroutine bc_recv_srl(igrid,i^D)
701 integer,
intent(in) :: igrid,i^D
703 integer :: ipe_neighbor
705 ipe_neighbor=neighbor(2,i^d,igrid)
706 if (ipe_neighbor/=mype)
then
708 itag=(3**^nd+4**^nd)*(igrid-1)+{(i^d+1)*3**(^d-1)+}
711 if(stagger_grid)
then
719 end subroutine bc_recv_srl
722 subroutine bc_recv_restrict(igrid,i^D)
723 integer,
intent(in) :: igrid,i^D
725 integer :: ic^D,inc^D,ipe_neighbor
727 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
728 inc^db=2*i^db+ic^db\}
729 ipe_neighbor=neighbor_child(2,inc^d,igrid)
730 if (ipe_neighbor/=mype)
then
732 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
733 call mpi_irecv(psb(igrid)%w,1,
type_recv_r(inc^d), &
735 if(stagger_grid)
then
738 mpi_double_precision,ipe_neighbor,itag, &
745 end subroutine bc_recv_restrict
748 subroutine bc_send_srl(igrid,i^D)
749 integer,
intent(in) :: igrid,i^D
751 integer :: n_i^D,ipole,idir,ineighbor,ipe_neighbor,ixS^L
753 ipe_neighbor=neighbor(2,i^d,igrid)
754 if(ipe_neighbor/=mype)
then
755 ineighbor=neighbor(1,i^d,igrid)
756 ipole=neighbor_pole(i^d,igrid)
760 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
764 if(stagger_grid)
then
771 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
784 n_i^d=i^d^d%n_i^dd=-i^dd;\}
786 if (isend_buf(ipwbuf)/=0)
then
789 deallocate(pwbuf(ipwbuf)%w)
791 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
792 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
795 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
796 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
797 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
800 ipwbuf=1+modulo(ipwbuf,
npwbuf)
801 if(stagger_grid)
then
808 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
820 end subroutine bc_send_srl
823 subroutine bc_send_restrict(igrid,i^D)
824 integer,
intent(in) :: igrid,i^D
826 integer :: ic^D,n_inc^D,ipole,idir,ineighbor,ipe_neighbor,ixS^L
828 ipe_neighbor=neighbor(2,i^d,igrid)
829 if(ipe_neighbor/=mype)
then
830 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
831 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
832 ineighbor=neighbor(1,i^d,igrid)
833 ipole=neighbor_pole(i^d,igrid)
837 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
841 if(stagger_grid)
then
848 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
853 mpi_double_precision,ipe_neighbor,itag, &
862 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
864 if(isend_buf(ipwbuf)/=0)
then
867 deallocate(pwbuf(ipwbuf)%w)
869 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
870 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psc(igrid)%w,
ixcog^l,ixs^l,ipole)
873 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
874 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
875 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
878 ipwbuf=1+modulo(ipwbuf,
npwbuf)
879 if(stagger_grid)
then
886 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
891 mpi_double_precision,ipe_neighbor,itag, &
899 end subroutine bc_send_restrict
902 subroutine bc_fill_srl(igrid,i^D)
903 integer,
intent(in) :: igrid,i^D
905 integer :: ineighbor,ipe_neighbor,ipole,ixS^L,ixR^L,n_i^D,idir
907 ipe_neighbor=neighbor(2,i^d,igrid)
908 if(ipe_neighbor==mype)
then
909 ineighbor=neighbor(1,i^d,igrid)
910 ipole=neighbor_pole(i^d,igrid)
915 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
916 psb(igrid)%w(ixs^s,nwhead:nwtail)
917 if(stagger_grid)
then
921 psb(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
928 n_i^d=i^d^d%n_i^dd=-i^dd;\}
931 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
932 if(stagger_grid)
then
936 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^l,psb(igrid)%ws,ixgs^ll,ixs^l,idir,ipole)
942 end subroutine bc_fill_srl
945 subroutine bc_fill_restrict(igrid,i^D)
946 integer,
intent(in) :: igrid,i^D
948 integer :: ic^D,n_inc^D,ixS^L,ixR^L,ipe_neighbor,ineighbor,ipole,idir
950 ipe_neighbor=neighbor(2,i^d,igrid)
951 if(ipe_neighbor==mype)
then
952 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
953 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
954 ineighbor=neighbor(1,i^d,igrid)
955 ipole=neighbor_pole(i^d,igrid)
960 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
961 psc(igrid)%w(ixs^s,nwhead:nwtail)
962 if(stagger_grid)
then
966 psb(ineighbor)%ws(ixr^s,idir)=psc(igrid)%ws(ixs^s,idir)
973 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
976 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^l,psc(igrid)%w,
ixcog^l,ixs^l,ipole)
977 if(stagger_grid)
then
982 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^l,psc(igrid)%ws,
ixcogs^l,ixs^l,idir,ipole)
988 end subroutine bc_fill_restrict
991 subroutine bc_fill_srl_stg(igrid,i^D)
992 integer,
intent(in) :: igrid,i^D
994 integer :: ixS^L,ixR^L,n_i^D,idir,ineighbor,ipe_neighbor,ipole
996 ipe_neighbor=neighbor(2,i^d,igrid)
997 if(ipe_neighbor/=mype)
then
998 ineighbor=neighbor(1,i^d,igrid)
999 ipole=neighbor_pole(i^d,igrid)
1011 shape=shape(psb(igrid)%ws(ixs^s,idir)))
1017 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1025 shape=shape(psb(igrid)%ws(ixs^s,idir)))
1027 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^l,pole_buf%ws,ixgs^ll,ixs^l,idir,ipole)
1032 end subroutine bc_fill_srl_stg
1035 subroutine bc_fill_restrict_stg(igrid,i^D)
1036 integer,
intent(in) :: igrid,i^D
1038 integer :: ipole,ic^D,inc^D,ineighbor,ipe_neighbor,ixS^L,ixR^L,n_i^D,idir
1040 ipole=neighbor_pole(i^d,igrid)
1043 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1044 inc^db=2*i^db+ic^db\}
1045 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1046 if(ipe_neighbor/=mype)
then
1047 ineighbor=neighbor_child(1,inc^d,igrid)
1054 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1060 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1061 inc^db=2*i^db+ic^db\}
1062 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1063 if(ipe_neighbor/=mype)
then
1064 ineighbor=neighbor_child(1,inc^d,igrid)
1067 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1077 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1078 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^
l,pole_buf%ws,ixgs^ll,ixr^
l,idir,ipole)
1085 end subroutine bc_fill_restrict_stg
1088 subroutine bc_recv_prolong(igrid,i^D)
1089 integer,
intent(in) :: igrid,i^D
1091 integer :: ic^D,ipe_neighbor,inc^D
1093 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1094 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1096 ipe_neighbor=neighbor(2,i^d,igrid)
1097 if (ipe_neighbor/=mype)
then
1100 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
1101 call mpi_irecv(psc(igrid)%w,1,
type_recv_p(inc^d), &
1103 if(stagger_grid)
then
1106 mpi_double_precision,ipe_neighbor,itag,&
1112 end subroutine bc_recv_prolong
1115 subroutine bc_send_prolong(igrid,i^D)
1116 integer,
intent(in) :: igrid,i^D
1118 integer :: ic^D,inc^D,n_i^D,n_inc^D,ineighbor,ipe_neighbor,ixS^L,ipole,idir
1120 ipole=neighbor_pole(i^d,igrid)
1122 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1123 inc^db=2*i^db+ic^db\}
1124 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1125 if(ipe_neighbor/=mype)
then
1126 ineighbor=neighbor_child(1,inc^d,igrid)
1131 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1132 call mpi_isend(psb(igrid)%w,1,
type_send_p(inc^d), &
1135 if(stagger_grid)
then
1142 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1143 ibuf_start=ibuf_next
1147 mpi_double_precision,ipe_neighbor,itag, &
1156 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1158 if(isend_buf(ipwbuf)/=0)
then
1161 deallocate(pwbuf(ipwbuf)%w)
1163 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
1164 call pole_buffer(pwbuf(ipwbuf)%w,ixs^l,ixs^l,psb(igrid)%w,ixg^ll,ixs^l,ipole)
1167 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1168 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
1169 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
1172 ipwbuf=1+modulo(ipwbuf,
npwbuf)
1173 if(stagger_grid)
then
1180 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1181 ibuf_start=ibuf_next
1185 mpi_double_precision,ipe_neighbor,itag, &
1194 end subroutine bc_send_prolong
1197 subroutine bc_fill_prolong(igrid,i^D)
1198 integer,
intent(in) :: igrid,i^D
1200 integer :: ipe_neighbor,ineighbor,ixS^L,ixR^L,ic^D,inc^D,n_i^D,n_inc^D,ipole,idir
1202 ipole=neighbor_pole(i^d,igrid)
1205 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1206 inc^db=2*i^db+ic^db\}
1207 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1208 if(ipe_neighbor==mype)
then
1210 ineighbor=neighbor_child(1,inc^d,igrid)
1214 psc(ineighbor)%w(ixr^s,nwhead:nwtail) &
1215 =psb(igrid)%w(ixs^s,nwhead:nwtail)
1216 if(stagger_grid)
then
1220 psc(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
1226 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1227 inc^db=2*i^db+ic^db\}
1228 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1229 if(ipe_neighbor==mype)
then
1231 ineighbor=neighbor_child(1,inc^d,igrid)
1234 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1237 call pole_copy(psc(ineighbor)%w,
ixcog^
l,ixr^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
1238 if(stagger_grid)
then
1242 call pole_copy_stg(psc(ineighbor)%ws,
ixcogs^
l,ixr^
l,psb(igrid)%ws,ixgs^ll,ixs^
l,idir,ipole)
1248 end subroutine bc_fill_prolong
1250 subroutine gc_prolong(igrid)
1251 integer,
intent(in) :: igrid
1253 integer :: i^D,idims,iside
1254 logical,
dimension(-1:1^D&) :: NeedProlong
1258 if (skip_direction([ i^d ])) cycle
1259 if (neighbor_type(i^d,igrid)==neighbor_coarse)
then
1260 call bc_prolong(igrid,i^d)
1261 needprolong(i^d)=.true.
1264 if(stagger_grid)
then
1275 if (needprolong(i^dd))
call bc_prolong_stg(igrid,i^dd,needprolong)
1286 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1292 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1298 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1304 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1307 end subroutine gc_prolong
1310 subroutine bc_fill_prolong_stg(igrid,i^D)
1311 integer,
intent(in) :: igrid,i^D
1313 integer :: ipe_neighbor,ineighbor,ipole,ixR^L,ic^D,inc^D,n_inc^D,idir
1315 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1316 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1318 ipe_neighbor=neighbor(2,i^d,igrid)
1319 if(ipe_neighbor/=mype)
then
1320 ineighbor=neighbor(1,i^d,igrid)
1321 ipole=neighbor_pole(i^d,igrid)
1330 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1337 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
1345 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1346 call pole_copy_stg(psc(igrid)%ws,
ixcogs^l,ixr^l,pole_buf%ws,ixgs^ll,ixr^l,idir,ipole)
1352 end subroutine bc_fill_prolong_stg
1355 subroutine bc_prolong(igrid,i^D)
1359 double precision :: dxFi^D, dxCo^D, xFimin^D, xComin^D, invdxCo^D
1360 integer :: i^D,igrid
1361 integer :: ixFi^L,ixCo^L,ii^D, idims,iside,ixB^L
1364 dxfi^d=rnode(rpdx^d_,igrid);
1366 invdxco^d=1.d0/dxco^d;
1372 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1373 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1375 if(phyboundblock(igrid).and.
bcphys)
then
1378 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1379 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1383 if(neighbor_type(-1,0,0,igrid)==neighbor_boundary .or. &
1384 neighbor_type(1,0,0,igrid)==neighbor_boundary)
then
1385 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary) ixcomin2=ixcommin2
1386 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1387 if(neighbor_type(0,1,0,igrid)==neighbor_boundary) ixcomax2=ixcommax2
1388 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1390 else if(idims == 2)
then
1391 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary .or. &
1392 neighbor_type(0,1,0,igrid)==neighbor_boundary)
then
1393 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1394 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1399 ii^d=kr(^d,idims)*(2*iside-3);
1400 if(neighbor_type(ii^d,igrid)/=neighbor_boundary) cycle
1401 if(( {(iside==1.and.idims==^d.and.ixcomin^d<ixcogmin^d+nghostcells)|.or.} ) &
1402 .or.( {(iside==2.and.idims==^d.and.ixcomax^d>ixcogmax^d-nghostcells)|.or. }))
then
1403 {ixbmin^d=merge(ixcogmin^d,ixcomin^d,idims==^d);}
1404 {ixbmax^d=merge(ixcogmax^d,ixcomax^d,idims==^d);}
1405 call bc_phys(iside,idims,time,0.d0,psc(igrid),
ixcog^l,ixb^l)
1411 if(prolongprimitive)
then
1413 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1414 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1419 call interpolation_copy(igrid,ixfi^l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1421 call interpolation_linear(igrid,ixfi^l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1424 if(prolongprimitive)
then
1429 end subroutine bc_prolong
1431 subroutine bc_prolong_stg(igrid,i^D,NeedProlong)
1433 double precision :: dxFi^D,dxCo^D,xFimin^D,xComin^D,invdxCo^D
1434 integer :: igrid,i^D
1435 integer :: ixFi^L,ixCo^L
1436 logical,
dimension(-1:1^D&) :: NeedProlong
1437 logical :: fine_^Lin
1441 if(i^d>-1) fine_min^din=(.not.needprolong(i^dd-kr(^d,^dd)).and.neighbor_type(i^dd-kr(^d,^dd),igrid)/=1)
1442 if(i^d<1) fine_max^din=(.not.needprolong(i^dd+kr(^d,^dd)).and.neighbor_type(i^dd+kr(^d,^dd),igrid)/=1)
1447 dxfi^d=rnode(rpdx^d_,igrid);
1449 invdxco^d=1.d0/dxco^d;
1451 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1452 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1457 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1458 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1460 if(prolongprimitive)
call phys_to_primitive(ixg^ll,ixfi^l,psb(igrid)%w,psb(igrid)%x)
1462 call prolong_2nd_stg(psc(igrid),psb(igrid),ixco^l,ixfi^l,dxco^d,xcomin^d,dxfi^d,xfimin^d,.true.,fine_^lin)
1464 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^l,psb(igrid)%w,psb(igrid)%x)
1467 needprolong(i^d)=.false.
1469 end subroutine bc_prolong_stg
1471 subroutine interpolation_linear(igrid,ixFi^L,dxFi^D,xFimin^D, &
1472 dxCo^D,invdxCo^D,xComin^D)
1474 integer,
intent(in) :: igrid, ixFi^L
1475 double precision,
intent(in) :: dxFi^D, xFimin^D,dxCo^D, invdxCo^D, xComin^D
1477 double precision :: xCo^D, xFi^D, eta^D
1478 double precision :: slopeL, slopeR, slopeC, signC, signR
1479 double precision :: slope(1:nw,ndim)
1481 double precision :: signedfactorhalf^D
1482 integer :: ixCo^D, jxCo^D, hxCo^D, ixFi^D, ix^D, iw, idims, nwmin,nwmax
1487 if(prolongprimitive)
then
1495 {
do ixfi^db = ixfi^lim^db
1498 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1503 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1
1507 xco^db=xcomin^db+(dble(ixco^db)-half)*dxco^db \}
1513 if(slab_uniform)
then
1522 eta^d=(xfi^d-xco^d)*invdxco^d;
1556 ix^d=2*int((ixfi^d+ixmlo^d)/2)-ixmlo^d;
1557 {
if(xfi^d>xco^d)
then
1558 signedfactorhalf^d=0.5d0
1560 signedfactorhalf^d=-0.5d0
1562 eta^d=signedfactorhalf^d*(one-psb(igrid)%dvolume(ixfi^dd) &
1563 /sum(psb(igrid)%dvolume(ix^d:ix^d+1^d%ixFi^dd))) \}
1570 hxco^d=ixco^d-kr(^d,idims)\
1571 jxco^d=ixco^d+kr(^d,idims)\
1574 slopel=psc(igrid)%w(ixco^d,iw)-psc(igrid)%w(hxco^d,iw)
1575 sloper=psc(igrid)%w(jxco^d,iw)-psc(igrid)%w(ixco^d,iw)
1576 slopec=half*(sloper+slopel)
1579 signr=sign(one,sloper)
1580 signc=sign(one,slopec)
1598 slope(iw,idims)=signc*max(zero,min(dabs(slopec), &
1599 signc*slopel,signc*sloper))
1605 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)+&
1606 {(slope(nwmin:nwmax,^d)*eta^d)+}
1610 if(prolongprimitive)
then
1612 call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1615 end subroutine interpolation_linear
1617 subroutine interpolation_copy(igrid, ixFi^L,dxFi^D,xFimin^D, &
1618 dxCo^D,invdxCo^D,xComin^D)
1620 integer,
intent(in) :: igrid, ixFi^L
1621 double precision,
intent(in) :: dxFi^D, xFimin^D,dxCo^D, invdxCo^D, xComin^D
1623 double precision :: xFi^D
1624 integer :: ixCo^D, ixFi^D, nwmin,nwmax
1626 if(prolongprimitive)
then
1634 {
do ixfi^db = ixfi^lim^db
1636 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1640 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1\}
1643 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)
1647 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1649 end subroutine interpolation_copy
1651 subroutine pole_copy(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1653 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,ipole
1654 double precision :: wrecv(ixIR^S,1:nw), wsend(ixIS^S,1:nw)
1656 integer :: iw, iside, iB
1660 iside=int((i^d+3)/2)
1663 select case (typeboundary(iw,ib))
1665 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1667 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1669 call mpistop(
"Pole boundary condition should be symm or asymm")
1674 end subroutine pole_copy
1676 subroutine pole_copy_stg(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,idirs,ipole)
1678 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,idirs,ipole
1680 double precision :: wrecv(ixIR^S,1:nws), wsend(ixIS^S,1:nws)
1681 integer :: iB, iside
1685 iside=int((i^d+3)/2)
1687 select case (typeboundary(iw_mag(idirs),ib))
1689 wrecv(ixr^s,idirs) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1691 wrecv(ixr^s,idirs) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1693 call mpistop(
"Pole boundary condition should be symm or asymm")
1698 end subroutine pole_copy_stg
1700 subroutine pole_buffer(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1702 integer,
intent(in) :: ixIR^L,ixR^L,ixIS^L,ixS^L,ipole
1703 double precision :: wrecv(ixIR^S,nwhead:nwtail), wsend(ixIS^S,1:nw)
1705 integer :: iw, iside, iB
1709 iside=int((i^d+3)/2)
1712 select case (typeboundary(iw,ib))
1714 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1716 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1718 call mpistop(
"Pole boundary condition should be symm or asymm")
1723 end subroutine pole_buffer