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
379 integer :: ibuf_start, ibuf_next
381 integer,
dimension(1) :: shapes
384 time_bcin=mpi_wtime()
387 nwtail=nwstart+nwbc-1
396 do iigrid=1,igridstail; igrid=igrids(iigrid);
397 if(any(neighbor_type(:^d&,igrid)==neighbor_coarse))
then
427 do iigrid=1,igridstail; igrid=igrids(iigrid);
430 select case (neighbor_type(i^d,igrid))
431 case (neighbor_sibling)
432 call bc_recv_srl(igrid,i^d)
434 call bc_recv_restrict(igrid,i^d)
440 do iigrid=1,igridstail; igrid=igrids(iigrid);
443 select case (neighbor_type(i^d,igrid))
444 case (neighbor_sibling)
445 call bc_send_srl(igrid,i^d)
446 case (neighbor_coarse)
447 call bc_send_restrict(igrid,i^d)
454 if(stagger_grid)
then
462 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
466 do iigrid=1,igridstail; igrid=igrids(iigrid);
469 select case (neighbor_type(i^d,igrid))
470 case(neighbor_sibling)
471 call bc_fill_srl(igrid,i^d)
472 case(neighbor_coarse)
473 call bc_fill_restrict(igrid,i^d)
479 if(stagger_grid)
then
483 do iigrid=1,igridstail; igrid=igrids(iigrid);
486 select case (neighbor_type(i^d,igrid))
487 case (neighbor_sibling)
488 call bc_fill_srl_stg(igrid,i^d)
490 call bc_fill_restrict_stg(igrid,i^d)
504 do iigrid=1,igridstail; igrid=igrids(iigrid);
507 if (neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_recv_prolong(igrid,i^d)
511 do iigrid=1,igridstail; igrid=igrids(iigrid);
514 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_send_prolong(igrid,i^d)
521 if(stagger_grid)
then
527 if (isend_buf(ipwbuf)/=0)
deallocate(pwbuf(ipwbuf)%w)
532 do iigrid=1,igridstail; igrid=igrids(iigrid);
535 if (neighbor_type(i^d,igrid)==neighbor_fine)
call bc_fill_prolong(igrid,i^d)
540 if(stagger_grid)
then
543 do iigrid=1,igridstail; igrid=igrids(iigrid);
546 if(neighbor_type(i^d,igrid)==neighbor_coarse)
call bc_fill_prolong_stg(igrid,i^d)
552 do iigrid=1,igridstail; igrid=igrids(iigrid);
553 call gc_prolong(igrid)
559 if(
associated(usr_prepare_boundary))
then
560 call usr_prepare_boundary(time, qdt)
563 do iigrid=1,igridstail; igrid=igrids(iigrid);
564 if(.not.phyboundblock(igrid)) cycle
565 call fill_boundary_after_gc(igrid)
571 if(
bcphys.and.
associated(phys_boundary_adjust))
then
573 do iigrid=1,igridstail; igrid=igrids(iigrid);
574 if(.not.phyboundblock(igrid)) cycle
575 call phys_boundary_adjust(igrid,psb)
580 time_bc=time_bc+(mpi_wtime()-time_bcin)
585 integer,
intent(in) :: dir(^nd)
587 if (all(dir == 0))
then
595 subroutine fill_boundary_after_gc(igrid)
597 integer,
intent(in) :: igrid
599 integer :: idims,iside,i^d,k^
l,ixb^
l
602 ^d&dxlevel(^d)=rnode(rpdx^d_,igrid);
609 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,igrid)==1)
610 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,igrid)==1)}
612 kmin2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0,-1,0,igrid)==1)
613 kmax2=merge(1, 0, idims .lt. 2 .and. neighbor_type(0, 1,0,igrid)==1)
614 kmin3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0,-1,igrid)==1)
615 kmax3=merge(1, 0, idims .lt. 3 .and. neighbor_type(0,0, 1,igrid)==1)}
616 ixbmin^d=ixglo^d+kmin^d*nghostcells;
617 ixbmax^d=ixghi^d-kmax^d*nghostcells;
619 i^d=kr(^d,idims)*(2*iside-3);
620 if (aperiodb(idims))
then
621 if (neighbor_type(i^d,igrid) /= neighbor_boundary .and. &
622 .not. psb(igrid)%is_physical_boundary(2*idims-2+iside)) cycle
624 if (neighbor_type(i^d,igrid) /= neighbor_boundary) cycle
630 call bc_phys(iside,idims,time,qdt,psb(igrid),ixg^ll,ixb^
l)
634 end subroutine fill_boundary_after_gc
637 subroutine bc_recv_srl(igrid,i^D)
638 integer,
intent(in) :: igrid,i^d
640 integer :: ipe_neighbor
642 ipe_neighbor=neighbor(2,i^d,igrid)
643 if (ipe_neighbor/=mype)
then
645 itag=(3**^nd+4**^nd)*(igrid-1)+{(i^d+1)*3**(^d-1)+}
648 if(stagger_grid)
then
656 end subroutine bc_recv_srl
659 subroutine bc_recv_restrict(igrid,i^D)
660 integer,
intent(in) :: igrid,i^d
662 integer :: ic^d,inc^d,ipe_neighbor
664 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
665 inc^db=2*i^db+ic^db\}
666 ipe_neighbor=neighbor_child(2,inc^d,igrid)
667 if (ipe_neighbor/=mype)
then
669 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
670 call mpi_irecv(psb(igrid)%w,1,
type_recv_r(inc^d), &
672 if(stagger_grid)
then
675 mpi_double_precision,ipe_neighbor,itag, &
682 end subroutine bc_recv_restrict
685 subroutine bc_send_srl(igrid,i^D)
686 integer,
intent(in) :: igrid,i^d
688 integer :: n_i^d,ipole,idir,ineighbor,ipe_neighbor,ixs^
l
690 ipe_neighbor=neighbor(2,i^d,igrid)
691 if(ipe_neighbor/=mype)
then
692 ineighbor=neighbor(1,i^d,igrid)
693 ipole=neighbor_pole(i^d,igrid)
697 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
700 if(stagger_grid)
then
707 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
719 n_i^d=i^d^d%n_i^dd=-i^dd;\}
721 if (isend_buf(ipwbuf)/=0)
then
724 deallocate(pwbuf(ipwbuf)%w)
726 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
727 call pole_buffer(pwbuf(ipwbuf)%w,ixs^
l,ixs^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
730 itag=(3**^nd+4**^nd)*(ineighbor-1)+{(n_i^d+1)*3**(^d-1)+}
731 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
732 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
734 ipwbuf=1+modulo(ipwbuf,
npwbuf)
735 if(stagger_grid)
then
742 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
753 end subroutine bc_send_srl
756 subroutine bc_send_restrict(igrid,i^D)
757 integer,
intent(in) :: igrid,i^d
759 integer :: ic^d,n_inc^d,ipole,idir,ineighbor,ipe_neighbor,ixs^
l
761 ipe_neighbor=neighbor(2,i^d,igrid)
762 if(ipe_neighbor/=mype)
then
763 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
764 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
765 ineighbor=neighbor(1,i^d,igrid)
766 ipole=neighbor_pole(i^d,igrid)
770 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
773 if(stagger_grid)
then
780 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
785 mpi_double_precision,ipe_neighbor,itag, &
793 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
795 if(isend_buf(ipwbuf)/=0)
then
798 deallocate(pwbuf(ipwbuf)%w)
800 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
801 call pole_buffer(pwbuf(ipwbuf)%w,ixs^
l,ixs^
l,psc(igrid)%w,
ixcog^
l,ixs^
l,ipole)
804 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
805 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
806 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
808 ipwbuf=1+modulo(ipwbuf,
npwbuf)
809 if(stagger_grid)
then
816 reshape(psc(igrid)%ws(ixs^s,idir),shapes)
821 mpi_double_precision,ipe_neighbor,itag, &
828 end subroutine bc_send_restrict
831 subroutine bc_fill_srl(igrid,i^D)
832 integer,
intent(in) :: igrid,i^d
834 integer :: ineighbor,ipe_neighbor,ipole,ixs^
l,ixr^
l,n_i^d,idir
836 ipe_neighbor=neighbor(2,i^d,igrid)
837 if(ipe_neighbor==mype)
then
838 ineighbor=neighbor(1,i^d,igrid)
839 ipole=neighbor_pole(i^d,igrid)
844 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
845 psb(igrid)%w(ixs^s,nwhead:nwtail)
846 if(stagger_grid)
then
850 psb(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
857 n_i^d=i^d^d%n_i^dd=-i^dd;\}
860 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
861 if(stagger_grid)
then
865 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^
l,psb(igrid)%ws,ixgs^ll,ixs^
l,idir,ipole)
871 end subroutine bc_fill_srl
874 subroutine bc_fill_restrict(igrid,i^D)
875 integer,
intent(in) :: igrid,i^d
877 integer :: ic^d,n_inc^d,ixs^
l,ixr^
l,ipe_neighbor,ineighbor,ipole,idir
879 ipe_neighbor=neighbor(2,i^d,igrid)
880 if(ipe_neighbor==mype)
then
881 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
882 if({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
883 ineighbor=neighbor(1,i^d,igrid)
884 ipole=neighbor_pole(i^d,igrid)
889 psb(ineighbor)%w(ixr^s,nwhead:nwtail)=&
890 psc(igrid)%w(ixs^s,nwhead:nwtail)
891 if(stagger_grid)
then
895 psb(ineighbor)%ws(ixr^s,idir)=psc(igrid)%ws(ixs^s,idir)
902 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
905 call pole_copy(psb(ineighbor)%w,ixg^ll,ixr^
l,psc(igrid)%w,
ixcog^
l,ixs^
l,ipole)
906 if(stagger_grid)
then
911 call pole_copy_stg(psb(ineighbor)%ws,ixgs^ll,ixr^
l,psc(igrid)%ws,
ixcogs^
l,ixs^
l,idir,ipole)
917 end subroutine bc_fill_restrict
920 subroutine bc_fill_srl_stg(igrid,i^D)
921 integer,
intent(in) :: igrid,i^d
923 integer :: ixs^
l,ixr^
l,n_i^d,idir,ineighbor,ipe_neighbor,ipole
925 ipe_neighbor=neighbor(2,i^d,igrid)
926 if(ipe_neighbor/=mype)
then
927 ineighbor=neighbor(1,i^d,igrid)
928 ipole=neighbor_pole(i^d,igrid)
940 shape=shape(psb(igrid)%ws(ixs^s,idir)))
946 n_i^d=i^d^d%n_i^dd=-i^dd;\}
954 shape=shape(psb(igrid)%ws(ixs^s,idir)))
956 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^
l,pole_buf%ws,ixgs^ll,ixs^
l,idir,ipole)
961 end subroutine bc_fill_srl_stg
964 subroutine bc_fill_restrict_stg(igrid,i^D)
965 integer,
intent(in) :: igrid,i^d
967 integer :: ipole,ic^d,inc^d,ineighbor,ipe_neighbor,ixs^
l,ixr^
l,n_i^d,idir
969 ipole=neighbor_pole(i^d,igrid)
972 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
973 inc^db=2*i^db+ic^db\}
974 ipe_neighbor=neighbor_child(2,inc^d,igrid)
975 if(ipe_neighbor/=mype)
then
976 ineighbor=neighbor_child(1,inc^d,igrid)
983 shape=shape(psb(igrid)%ws(ixr^s,idir)))
989 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
990 inc^db=2*i^db+ic^db\}
991 ipe_neighbor=neighbor_child(2,inc^d,igrid)
992 if(ipe_neighbor/=mype)
then
993 ineighbor=neighbor_child(1,inc^d,igrid)
996 n_i^d=i^d^d%n_i^dd=-i^dd;\}
1006 shape=shape(psb(igrid)%ws(ixr^s,idir)))
1007 call pole_copy_stg(psb(igrid)%ws,ixgs^ll,ixr^
l,pole_buf%ws,ixgs^ll,ixr^
l,idir,ipole)
1014 end subroutine bc_fill_restrict_stg
1017 subroutine bc_recv_prolong(igrid,i^D)
1018 integer,
intent(in) :: igrid,i^d
1020 integer :: ic^d,ipe_neighbor,inc^d
1022 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1023 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1025 ipe_neighbor=neighbor(2,i^d,igrid)
1026 if (ipe_neighbor/=mype)
then
1029 itag=(3**^nd+4**^nd)*(igrid-1)+3**^nd+{inc^d*4**(^d-1)+}
1030 call mpi_irecv(psc(igrid)%w,1,
type_recv_p(inc^d), &
1032 if(stagger_grid)
then
1035 mpi_double_precision,ipe_neighbor,itag,&
1041 end subroutine bc_recv_prolong
1044 subroutine bc_send_prolong(igrid,i^D)
1045 integer,
intent(in) :: igrid,i^d
1047 integer :: ic^d,inc^d,n_i^d,n_inc^d,ineighbor,ipe_neighbor,ixs^
l,ipole,idir
1049 ipole=neighbor_pole(i^d,igrid)
1051 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1052 inc^db=2*i^db+ic^db\}
1053 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1054 if(ipe_neighbor/=mype)
then
1055 ineighbor=neighbor_child(1,inc^d,igrid)
1060 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1061 call mpi_isend(psb(igrid)%w,1,
type_send_p(inc^d), &
1063 if(stagger_grid)
then
1070 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1071 ibuf_start=ibuf_next
1075 mpi_double_precision,ipe_neighbor,itag, &
1083 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1085 if(isend_buf(ipwbuf)/=0)
then
1088 deallocate(pwbuf(ipwbuf)%w)
1090 allocate(pwbuf(ipwbuf)%w(ixs^s,nwhead:nwtail))
1091 call pole_buffer(pwbuf(ipwbuf)%w,ixs^
l,ixs^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
1094 itag=(3**^nd+4**^nd)*(ineighbor-1)+3**^nd+{n_inc^d*4**(^d-1)+}
1095 isizes={(ixsmax^d-ixsmin^d+1)*}*nwbc
1096 call mpi_isend(pwbuf(ipwbuf)%w,isizes,mpi_double_precision, &
1098 ipwbuf=1+modulo(ipwbuf,
npwbuf)
1099 if(stagger_grid)
then
1106 reshape(psb(igrid)%ws(ixs^s,idir),shapes)
1107 ibuf_start=ibuf_next
1111 mpi_double_precision,ipe_neighbor,itag, &
1119 end subroutine bc_send_prolong
1122 subroutine bc_fill_prolong(igrid,i^D)
1123 integer,
intent(in) :: igrid,i^d
1125 integer :: ipe_neighbor,ineighbor,ixs^
l,ixr^
l,ic^d,inc^d,n_i^d,n_inc^d,ipole,idir
1127 ipole=neighbor_pole(i^d,igrid)
1130 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1131 inc^db=2*i^db+ic^db\}
1132 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1133 if(ipe_neighbor==mype)
then
1135 ineighbor=neighbor_child(1,inc^d,igrid)
1139 psc(ineighbor)%w(ixr^s,nwhead:nwtail) &
1140 =psb(igrid)%w(ixs^s,nwhead:nwtail)
1141 if(stagger_grid)
then
1145 psc(ineighbor)%ws(ixr^s,idir)=psb(igrid)%ws(ixs^s,idir)
1151 {
do ic^db=1+int((1-i^db)/2),2-int((1+i^db)/2)
1152 inc^db=2*i^db+ic^db\}
1153 ipe_neighbor=neighbor_child(2,inc^d,igrid)
1154 if(ipe_neighbor==mype)
then
1156 ineighbor=neighbor_child(1,inc^d,igrid)
1159 n_inc^d=inc^d^d%n_inc^dd=ic^dd-i^dd;\}
1162 call pole_copy(psc(ineighbor)%w,
ixcog^
l,ixr^
l,psb(igrid)%w,ixg^ll,ixs^
l,ipole)
1163 if(stagger_grid)
then
1167 call pole_copy_stg(psc(ineighbor)%ws,
ixcogs^
l,ixr^
l,psb(igrid)%ws,ixgs^ll,ixs^
l,idir,ipole)
1173 end subroutine bc_fill_prolong
1175 subroutine gc_prolong(igrid)
1176 integer,
intent(in) :: igrid
1178 integer :: i^d,idims,iside
1179 logical,
dimension(-1:1^D&) :: needprolong
1184 if (neighbor_type(i^d,igrid)==neighbor_coarse)
then
1185 call bc_prolong(igrid,i^d)
1186 needprolong(i^d)=.true.
1189 if(stagger_grid)
then
1200 if (needprolong(i^dd))
call bc_prolong_stg(igrid,i^dd,needprolong)
1211 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1217 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1223 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1229 if (needprolong(i^d))
call bc_prolong_stg(igrid,i^d,needprolong)
1232 end subroutine gc_prolong
1235 subroutine bc_fill_prolong_stg(igrid,i^D)
1236 integer,
intent(in) :: igrid,i^d
1238 integer :: ipe_neighbor,ineighbor,ipole,ixr^
l,ic^d,inc^d,n_inc^d,idir
1240 ic^d=1+modulo(node(pig^d_,igrid)-1,2);
1241 if ({.not.(i^d==0.or.i^d==2*ic^d-3)|.or.})
return
1243 ipe_neighbor=neighbor(2,i^d,igrid)
1244 if(ipe_neighbor/=mype)
then
1245 ineighbor=neighbor(1,i^d,igrid)
1246 ipole=neighbor_pole(i^d,igrid)
1255 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1262 n_inc^d=2*i^d+(3-ic^d)^d%n_inc^dd=-2*i^dd+ic^dd;\}
1270 shape=shape(psc(igrid)%ws(ixr^s,idir)))
1271 call pole_copy_stg(psc(igrid)%ws,
ixcogs^
l,ixr^
l,pole_buf%ws,ixgs^ll,ixr^
l,idir,ipole)
1277 end subroutine bc_fill_prolong_stg
1280 subroutine bc_prolong(igrid,i^D)
1284 double precision :: dxfi^d, dxco^d, xfimin^d, xcomin^d, invdxco^d
1285 integer :: i^d,igrid
1286 integer :: ixfi^
l,ixco^
l,ii^d, idims,iside,ixb^
l
1289 dxfi^d=rnode(rpdx^d_,igrid);
1291 invdxco^d=1.d0/dxco^d;
1297 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1298 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1300 if(phyboundblock(igrid).and.
bcphys)
then
1303 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1304 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1308 if(neighbor_type(-1,0,0,igrid)==neighbor_boundary .or. &
1309 neighbor_type(1,0,0,igrid)==neighbor_boundary)
then
1310 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary) ixcomin2=ixcommin2
1311 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1312 if(neighbor_type(0,1,0,igrid)==neighbor_boundary) ixcomax2=ixcommax2
1313 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1315 else if(idims == 2)
then
1316 if(neighbor_type(0,-1,0,igrid)==neighbor_boundary .or. &
1317 neighbor_type(0,1,0,igrid)==neighbor_boundary)
then
1318 if(neighbor_type(0,0,-1,igrid)==neighbor_boundary) ixcomin3=ixcommin3
1319 if(neighbor_type(0,0,1,igrid)==neighbor_boundary) ixcomax3=ixcommax3
1324 ii^d=kr(^d,idims)*(2*iside-3);
1325 if(neighbor_type(ii^d,igrid)/=neighbor_boundary) cycle
1326 if(( {(iside==1.and.idims==^d.and.ixcomin^d<ixcogmin^d+nghostcells)|.or.} ) &
1327 .or.( {(iside==2.and.idims==^d.and.ixcomax^d>ixcogmax^d-nghostcells)|.or. }))
then
1328 {ixbmin^d=merge(ixcogmin^d,ixcomin^d,idims==^d);}
1329 {ixbmax^d=merge(ixcogmax^d,ixcomax^d,idims==^d);}
1330 call bc_phys(iside,idims,time,0.d0,psc(igrid),
ixcog^
l,ixb^
l)
1336 if(prolongprimitive)
then
1338 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1339 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1344 call interpolation_copy(igrid,ixfi^
l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1346 call interpolation_linear(igrid,ixfi^
l,dxfi^d,xfimin^d,dxco^d,invdxco^d,xcomin^d)
1349 if(prolongprimitive)
then
1354 end subroutine bc_prolong
1356 subroutine bc_prolong_stg(igrid,i^D,NeedProlong)
1358 double precision :: dxfi^d,dxco^d,xfimin^d,xcomin^d,invdxco^d
1359 integer :: igrid,i^d
1360 integer :: ixfi^
l,ixco^
l
1361 logical,
dimension(-1:1^D&) :: needprolong
1362 logical :: fine_^lin
1366 if(i^d>-1) fine_min^din=(.not.needprolong(i^dd-kr(^d,^dd)).and.neighbor_type(i^dd-kr(^d,^dd),igrid)/=1)
1367 if(i^d<1) fine_max^din=(.not.needprolong(i^dd+kr(^d,^dd)).and.neighbor_type(i^dd+kr(^d,^dd),igrid)/=1)
1372 dxfi^d=rnode(rpdx^d_,igrid);
1374 invdxco^d=1.d0/dxco^d;
1376 xfimin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxfi^d;
1377 xcomin^d=rnode(rpxmin^d_,igrid)-dble(nghostcells)*dxco^d;
1382 ixcomin^d=int((xfimin^d+(dble(ixfimin^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1-1;
1383 ixcomax^d=int((xfimin^d+(dble(ixfimax^d)-half)*dxfi^d-xcomin^d)*invdxco^d)+1+1;
1385 if(prolongprimitive)
call phys_to_primitive(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1387 call prolong_2nd_stg(psc(igrid),psb(igrid),ixco^
l,ixfi^
l,dxco^d,xcomin^d,dxfi^d,xfimin^d,.true.,fine_^lin)
1389 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1392 needprolong(i^d)=.false.
1394 end subroutine bc_prolong_stg
1396 subroutine interpolation_linear(igrid,ixFi^L,dxFi^D,xFimin^D, &
1397 dxCo^D,invdxCo^D,xComin^D)
1399 integer,
intent(in) :: igrid, ixfi^
l
1400 double precision,
intent(in) :: dxfi^d, xfimin^d,dxco^d, invdxco^d, xcomin^d
1402 double precision :: xco^d, xfi^d, eta^d
1403 double precision :: slopel, sloper, slopec, signc, signr
1404 double precision :: slope(1:nw,ndim)
1406 double precision :: signedfactorhalf^d
1407 integer :: ixco^d, jxco^d, hxco^d, ixfi^d, ix^d, iw, idims, nwmin,nwmax
1412 if(prolongprimitive)
then
1420 {
do ixfi^db = ixfi^lim^db
1423 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1428 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1
1432 xco^db=xcomin^db+(dble(ixco^db)-half)*dxco^db \}
1438 if(slab_uniform)
then
1447 eta^d=(xfi^d-xco^d)*invdxco^d;
1481 ix^d=2*int((ixfi^d+ixmlo^d)/2)-ixmlo^d;
1482 {
if(xfi^d>xco^d)
then
1483 signedfactorhalf^d=0.5d0
1485 signedfactorhalf^d=-0.5d0
1487 eta^d=signedfactorhalf^d*(one-psb(igrid)%dvolume(ixfi^dd) &
1488 /sum(psb(igrid)%dvolume(ix^d:ix^d+1^d%ixFi^dd))) \}
1495 hxco^d=ixco^d-kr(^d,idims)\
1496 jxco^d=ixco^d+kr(^d,idims)\
1499 slopel=psc(igrid)%w(ixco^d,iw)-psc(igrid)%w(hxco^d,iw)
1500 sloper=psc(igrid)%w(jxco^d,iw)-psc(igrid)%w(ixco^d,iw)
1501 slopec=half*(sloper+slopel)
1504 signr=sign(one,sloper)
1505 signc=sign(one,slopec)
1523 slope(iw,idims)=signc*max(zero,min(dabs(slopec), &
1524 signc*slopel,signc*sloper))
1530 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)+&
1531 {(slope(nwmin:nwmax,^d)*eta^d)+}
1535 if(prolongprimitive)
then
1537 call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1540 end subroutine interpolation_linear
1542 subroutine interpolation_copy(igrid, ixFi^L,dxFi^D,xFimin^D, &
1543 dxCo^D,invdxCo^D,xComin^D)
1545 integer,
intent(in) :: igrid, ixfi^
l
1546 double precision,
intent(in) :: dxfi^d, xfimin^d,dxco^d, invdxco^d, xcomin^d
1548 double precision :: xfi^d
1549 integer :: ixco^d, ixfi^d, nwmin,nwmax
1551 if(prolongprimitive)
then
1559 {
do ixfi^db = ixfi^lim^db
1561 xfi^db=xfimin^db+(dble(ixfi^db)-half)*dxfi^db
1565 ixco^db=int((xfi^db-xcomin^db)*invdxco^db)+1\}
1568 psb(igrid)%w(ixfi^d,nwmin:nwmax)=psc(igrid)%w(ixco^d,nwmin:nwmax)
1572 if(prolongprimitive)
call phys_to_conserved(ixg^ll,ixfi^
l,psb(igrid)%w,psb(igrid)%x)
1574 end subroutine interpolation_copy
1576 subroutine pole_copy(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1578 integer,
intent(in) :: ixir^
l,ixr^
l,ixis^
l,ixs^
l,ipole
1579 double precision :: wrecv(ixir^s,1:nw), wsend(ixis^s,1:nw)
1581 integer :: iw, iside, ib
1585 iside=int((i^d+3)/2)
1588 select case (typeboundary(iw,ib))
1590 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1592 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1594 call mpistop(
"Pole boundary condition should be symm or asymm")
1599 end subroutine pole_copy
1601 subroutine pole_copy_stg(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,idirs,ipole)
1603 integer,
intent(in) :: ixir^
l,ixr^
l,ixis^
l,ixs^
l,idirs,ipole
1605 double precision :: wrecv(ixir^s,1:nws), wsend(ixis^s,1:nws)
1606 integer :: ib, iside
1610 iside=int((i^d+3)/2)
1612 select case (typeboundary(iw_mag(idirs),ib))
1614 wrecv(ixr^s,idirs) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1616 wrecv(ixr^s,idirs) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,idirs)
1618 call mpistop(
"Pole boundary condition should be symm or asymm")
1623 end subroutine pole_copy_stg
1625 subroutine pole_buffer(wrecv,ixIR^L,ixR^L,wsend,ixIS^L,ixS^L,ipole)
1627 integer,
intent(in) :: ixir^
l,ixr^
l,ixis^
l,ixs^
l,ipole
1628 double precision :: wrecv(ixir^s,nwhead:nwtail), wsend(ixis^s,1:nw)
1630 integer :: iw, iside, ib
1634 iside=int((i^d+3)/2)
1637 select case (typeboundary(iw,ib))
1639 wrecv(ixr^s,iw) = wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1641 wrecv(ixr^s,iw) =-wsend(ixsmax^d:ixsmin^d:-1^d%ixS^s,iw)
1643 call mpistop(
"Pole boundary condition should be symm or asymm")
1648 end subroutine pole_buffer