41 double precision,
intent(in) :: qLunit,qBunit
42 double precision :: xc1,xc2,dxm1,dxm2
43 integer,
dimension(MPI_STATUS_SIZE) :: statuss
44 integer :: file_handle,i
46 character(len=*),
intent(in) :: magnetogramname
51 inquire(file=magnetogramname,exist=aexist)
53 if(
mype==0)
write(*,
'(2a)')
"can not find file:",magnetogramname
54 call mpistop(
"no input magnetogram----init_b_fff_data")
56 call mpi_file_open(
icomm,magnetogramname,mpi_mode_rdonly,mpi_info_null,&
58 call mpi_file_read_all(file_handle,
nx1,1,mpi_integer,statuss,
ierrmpi)
59 call mpi_file_read_all(file_handle,
nx2,1,mpi_integer,statuss,
ierrmpi)
61 call mpi_file_read_all(file_handle,xc1,1,mpi_double_precision,statuss,
ierrmpi)
62 call mpi_file_read_all(file_handle,xc2,1,mpi_double_precision,statuss,
ierrmpi)
63 call mpi_file_read_all(file_handle,dxm1,1,mpi_double_precision,statuss,
ierrmpi)
64 call mpi_file_read_all(file_handle,dxm2,1,mpi_double_precision,statuss,
ierrmpi)
65 call mpi_file_read_all(file_handle,
bz0,
nx1*
nx2,mpi_double_precision,&
67 call mpi_file_close(file_handle,
ierrmpi)
71 xa1(i) = xc1 + (dble(i) - dble(
nx1)/2.d0 - 0.5d0)*dxm1
74 xa2(i) = xc2 + (dble(i) - dble(
nx2)/2.d0 - 0.5d0)*dxm2
89 print*,
'magnetogram xrange:',minval(
xa1),maxval(
xa1)
90 print*,
'magnetogram yrange:',minval(
xa2),maxval(
xa2)
94 print*,
'extrapolating 3D force-free field from an observed Bz '
95 print*,
'magnetogram of',
nx1,
'by',
nx2,
'pixels. Bzmax=',
bzmax
110 integer,
intent(in) :: ixI^L, ixO^L
111 integer,
optional,
intent(in) :: idir
112 double precision,
intent(in) :: x(ixI^S,1:ndim),alpha,zshift
113 double precision,
intent(inout) :: Bf(ixI^S,1:ndir)
115 double precision,
dimension(ixO^S) :: cos_az,sin_az,zk,bigr,r,r2,r3,cos_ar,sin_ar,g,dgdz
116 double precision :: gx(ixO^S,1:ndim),twopiinv
117 integer :: idim,ixp1,ixp2
122 zk(ixo^s)=x(ixo^s,3)-xprobmin3+zshift
123 cos_az(ixo^s)=dcos(alpha*zk(ixo^s))
124 sin_az(ixo^s)=dsin(alpha*zk(ixo^s))
128 bigr(ixo^s)=dsqrt((x(ixo^s,1)-
xa1(ixp1))**2+&
129 (x(ixo^s,2)-
xa2(ixp2))**2)
147 g=(zk*cos_ar*r-cos_az)*bigr
148 dgdz=(cos_ar*(r-zk**2*r3)-alpha*zk**2*sin_ar*r2+alpha*sin_az)*bigr
150 if(
present(idir))
then
155 bf(ixo^s,1)=bf(ixo^s,1)+
bz0(ixp1,ixp2)*((x(ixo^s,1)-
xa1(ixp1))*dgdz(ixo^s)&
156 +alpha*g(ixo^s)*(x(ixo^s,2)-
xa2(ixp2)))*bigr(ixo^s)
158 bf(ixo^s,2)=bf(ixo^s,2)+
bz0(ixp1,ixp2)*((x(ixo^s,2)-
xa2(ixp2))*dgdz(ixo^s)&
159 -alpha*g(ixo^s)*(x(ixo^s,1)-
xa1(ixp1)))*bigr(ixo^s)
161 bf(ixo^s,3)=bf(ixo^s,3)+
bz0(ixp1,ixp2)*(zk(ixo^s)*cos_ar(ixo^s)*r3(ixo^s)+alpha*&
162 zk(ixo^s)*sin_ar(ixo^s)*r2(ixo^s))
167 bf(ixo^s,:)=bf(ixo^s,:)*twopiinv
323 type(mg_box_t),
intent(in) :: box
324 integer,
intent(in) :: nc
325 integer,
intent(in) :: iv
326 integer,
intent(in) :: nb
327 integer,
intent(out) :: bc_type
329 double precision,
intent(out) :: bc(nc, nc)
331 double precision :: rr(nc, nc, 3)
332 double precision :: rmina,rminb,rmaxa,rmaxb,xmina,xminb,xmaxa,xmaxb
334 double precision :: wbn(ixG^T)
335 double precision,
allocatable :: xcoarse(:,:,:)
336 integer :: iigrid,igrid,ix^D,idir,ixbca,ixbcb,ixbcn,dlvl,wnc
338 bc_type = mg_bc_neumann
340 call mg_get_face_coords(box, nb, nc, rr)
348 if(mod(nb,2)==0)
then
353 rmina=rr(1,1,2)-0.5d0*box%dr(2)
354 rmaxa=rr(nc,1,2)+0.5d0*box%dr(2)
355 rminb=rr(1,1,3)-0.5d0*box%dr(3)
356 rmaxb=rr(1,nc,3)+0.5d0*box%dr(3)
357 do iigrid=1,igridstail; igrid=igrids(iigrid);
359 if(.not.
block%is_physical_boundary(nb)) cycle
362 wbn(ixbcn^%1ixg^t)=
block%ws(ixbcn^%1ixg^t,idir)
364 wbn(ixbcn^%1ixg^t)=half*(
block%w(ixbcn^%1ixg^t,iw_mag(idir))+
block%w(ixbcn+1^%1ixg^t,iw_mag(idir)))
366 xmina=
block%x(1,1,1,2)-0.5d0*
rnode(rpdx2_,igrid)
367 xmaxa=
block%x(1,ixghi2,1,2)+0.5d0*
rnode(rpdx2_,igrid)
368 xminb=
block%x(1,1,1,3)-0.5d0*
rnode(rpdx3_,igrid)
369 xmaxb=
block%x(1,1,ixghi3,3)+0.5d0*
rnode(rpdx3_,igrid)
370 if(xmina<rr(1,1,2) .and. xmaxa>rr(nc,1,2) .and. &
371 xminb<rr(1,1,3) .and. xmaxb>rr(1,nc,3))
then
374 ixbca=ceiling((rr(ix1,ix2,2)-xmina)/
rnode(rpdx2_,igrid))
375 ixbcb=ceiling((rr(ix1,ix2,3)-xminb)/
rnode(rpdx3_,igrid))
376 bc(ix1,ix2)=wbn(ixbcn,ixbca,ixbcb)
379 else if(
block%x(1,ixmlo2,1,2)>rmina .and.
block%x(1,ixmhi2,1,2)<rmaxa .and. &
380 block%x(1,1,ixmlo3,3)>rminb .and.
block%x(1,1,ixmhi3,3)<rmaxb)
then
383 allocate(xcoarse(wnc,wnc,2))
388 ixbca=ceiling((xcoarse(ix1,ix2,1)-rmina)/box%dr(2))
389 ixbcb=ceiling((xcoarse(ix1,ix2,2)-rminb)/box%dr(3))
398 if(mod(nb,2)==0)
then
403 rmina=rr(1,1,1)-0.5d0*box%dr(1)
404 rmaxa=rr(nc,1,1)+0.5d0*box%dr(1)
405 rminb=rr(1,1,3)-0.5d0*box%dr(3)
406 rmaxb=rr(1,nc,3)+0.5d0*box%dr(3)
407 do iigrid=1,igridstail; igrid=igrids(iigrid);
409 if(.not.
block%is_physical_boundary(nb)) cycle
411 wbn(ixbcn^%2ixg^t)=
block%ws(ixbcn^%2ixg^t,idir)
413 wbn(ixbcn^%2ixg^t)=half*(
block%w(ixbcn^%2ixg^t,iw_mag(idir))+
block%w(ixbcn+1^%2ixg^t,iw_mag(idir)))
415 xmina=
block%x(1,1,1,1)-0.5d0*
rnode(rpdx1_,igrid)
416 xmaxa=
block%x(ixghi1,1,1,1)+0.5d0*
rnode(rpdx1_,igrid)
417 xminb=
block%x(1,1,1,3)-0.5d0*
rnode(rpdx3_,igrid)
418 xmaxb=
block%x(1,1,ixghi3,3)+0.5d0*
rnode(rpdx3_,igrid)
419 if(xmina<rr(1,1,1) .and. xmaxa>rr(nc,1,1) .and. &
420 xminb<rr(1,1,3) .and. xmaxb>rr(1,nc,3))
then
423 ixbca=ceiling((rr(ix1,ix2,1)-xmina)/
rnode(rpdx1_,igrid))
424 ixbcb=ceiling((rr(ix1,ix2,3)-xminb)/
rnode(rpdx3_,igrid))
425 bc(ix1,ix2)=wbn(ixbca,ixbcn,ixbcb)
428 else if(
block%x(ixmlo1,1,1,1)>rmina .and.
block%x(ixmhi1,1,1,1)<rmaxa .and. &
429 block%x(1,1,ixmlo3,3)>rminb .and.
block%x(1,1,ixmhi3,3)<rmaxb)
then
432 allocate(xcoarse(wnc,wnc,2))
437 ixbca=ceiling((xcoarse(ix1,ix2,1)-rmina)/box%dr(1))
438 ixbcb=ceiling((xcoarse(ix1,ix2,2)-rminb)/box%dr(3))
447 if(mod(nb,2)==0)
then
452 rmina=rr(1,1,1)-0.5d0*box%dr(1)
453 rmaxa=rr(nc,1,1)+0.5d0*box%dr(1)
454 rminb=rr(1,1,2)-0.5d0*box%dr(2)
455 rmaxb=rr(1,nc,2)+0.5d0*box%dr(2)
456 do iigrid=1,igridstail; igrid=igrids(iigrid);
458 if(.not.
block%is_physical_boundary(nb)) cycle
460 wbn(ixbcn^%3ixg^t)=
block%ws(ixbcn^%3ixg^t,idir)
462 wbn(ixbcn^%3ixg^t)=half*(
block%w(ixbcn^%3ixg^t,iw_mag(idir))+
block%w(ixbcn+1^%3ixg^t,iw_mag(idir)))
464 xmina=
block%x(1,1,1,1)-0.5d0*
rnode(rpdx1_,igrid)
465 xmaxa=
block%x(ixghi1,1,1,1)+0.5d0*
rnode(rpdx1_,igrid)
466 xminb=
block%x(1,1,1,2)-0.5d0*
rnode(rpdx2_,igrid)
467 xmaxb=
block%x(1,ixghi2,1,2)+0.5d0*
rnode(rpdx2_,igrid)
468 if(xmina<rr(1,1,1) .and. xmaxa>rr(nc,1,1) .and. &
469 xminb<rr(1,1,2) .and. xmaxb>rr(1,nc,2))
then
472 ixbca=ceiling((rr(ix1,ix2,1)-xmina)/
rnode(rpdx1_,igrid))
473 ixbcb=ceiling((rr(ix1,ix2,2)-xminb)/
rnode(rpdx2_,igrid))
474 bc(ix1,ix2)=wbn(ixbca,ixbcb,ixbcn)
477 else if(
block%x(ixmlo1,1,1,1)>rmina .and.
block%x(ixmhi1,1,1,1)<rmaxa .and. &
478 block%x(1,ixmlo2,1,2)>rminb .and.
block%x(1,ixmhi2,1,2)<rmaxb)
then
481 allocate(xcoarse(wnc,wnc,2))
486 ixbca=ceiling((xcoarse(ix1,ix2,1)-rmina)/box%dr(1))
487 ixbcb=ceiling((xcoarse(ix1,ix2,2)-rminb)/box%dr(2))