calculate magnetic field from vector potential A at cell edges
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| integer, | intent(in) | :: | ixIsmin1 | |||
| integer, | intent(in) | :: | ixIsmin2 | |||
| integer, | intent(in) | :: | ixIsmin3 | |||
| integer, | intent(in) | :: | ixIsmax1 | |||
| integer, | intent(in) | :: | ixIsmax2 | |||
| integer, | intent(in) | :: | ixIsmax3 | |||
| integer, | intent(in) | :: | ixImin1 | |||
| integer, | intent(in) | :: | ixImin2 | |||
| integer, | intent(in) | :: | ixImin3 | |||
| integer, | intent(in) | :: | ixImax1 | |||
| integer, | intent(in) | :: | ixImax2 | |||
| integer, | intent(in) | :: | ixImax3 | |||
| integer, | intent(in) | :: | ixOmin1 | |||
| integer, | intent(in) | :: | ixOmin2 | |||
| integer, | intent(in) | :: | ixOmin3 | |||
| integer, | intent(in) | :: | ixOmax1 | |||
| integer, | intent(in) | :: | ixOmax2 | |||
| integer, | intent(in) | :: | ixOmax3 | |||
| double precision, | intent(inout) | :: | ws(ixIsmin1:ixIsmax1,ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:nws) | |||
| double precision, | intent(in) | :: | x(ixImin1:ixImax1,ixImin2:ixImax2,ixImin3:ixImax3,1:ndim) | |||
| double precision, | intent(inout) | :: | A(ixIsmin1:ixIsmax1,ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:3) |
subroutine b_from_vector_potentialA(ixIsmin1,ixIsmin2,ixIsmin3,ixIsmax1,& ixIsmax2,ixIsmax3, ixImin1,ixImin2,ixImin3,ixImax1,ixImax2,ixImax3,& ixOmin1,ixOmin2,ixOmin3,ixOmax1,ixOmax2,ixOmax3, ws, x, A) use mod_global_parameters use mod_usr_methods, only: usr_init_vector_potential use mod_comm_lib, only: mpistop integer, intent(in) :: ixIsmin1,ixIsmin2,ixIsmin3,ixIsmax1,& ixIsmax2,ixIsmax3, ixImin1,ixImin2,ixImin3,ixImax1,ixImax2,ixImax3,& ixOmin1,ixOmin2,ixOmin3,ixOmax1,ixOmax2,ixOmax3 double precision, intent(inout) :: ws(ixIsmin1:ixIsmax1,& ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:nws),A(ixIsmin1:ixIsmax1,& ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:3) double precision, intent(in) :: x(ixImin1:ixImax1,ixImin2:ixImax2,& ixImin3:ixImax3,1:ndim) integer :: ixCmin1,ixCmin2,ixCmin3,ixCmax1,& ixCmax2,ixCmax3, hxCmin1,hxCmin2,hxCmin3,hxCmax1,hxCmax2,hxCmax3, idim1,& idim2, idir double precision :: xC(ixIsmin1:ixIsmax1,& ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:ndim),xCC(ixIsmin1:ixIsmax1,& ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:ndim) double precision :: circ(ixIsmin1:ixIsmax1,& ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1:ndim) ! The edge integral below weights the vector potential by block%dsC, the ! cell-face lengths. Those are no longer built: this routine is the only ! reader, it has no callers, and it needs stagger_grid, which this fork ! does not support. Fail here rather than touch an unassociated pointer. call mpistop("b_from_vector_potentialA needs block%dsC, which is no & &longer built - see geo_t in mod_physicaldata") A=zero ! extend one layer of cell center locations in xCC xC=0.d0 xCC=0.d0 xCC(ixImin1:ixImax1,ixImin2:ixImax2,ixImin3:ixImax3,& 1:ndim)=x(ixImin1:ixImax1,ixImin2:ixImax2,ixImin3:ixImax3,1:ndim) xCC(ixIsmin1,ixImin2:ixImax2,ixImin3:ixImax3,1:ndim)=x(ixImin1,& ixImin2:ixImax2,ixImin3:ixImax3,1:ndim) xCC(ixIsmin1,ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,1)=x(ixImin1,ixImin2,& ixImin3,1)-block%dx(ixImin1,ixImin2,ixImin3,1) xCC(ixImin1:ixImax1,ixIsmin2,ixImin3:ixImax3,1:ndim)=x(ixImin1:ixImax1,& ixImin2,ixImin3:ixImax3,1:ndim) xCC(ixIsmin1:ixIsmax1,ixIsmin2,ixIsmin3:ixIsmax3,2)=x(ixImin1,ixImin2,& ixImin3,2)-block%dx(ixImin1,ixImin2,ixImin3,2) xCC(ixImin1:ixImax1,ixImin2:ixImax2,ixIsmin3,1:ndim)=x(ixImin1:ixImax1,& ixImin2:ixImax2,ixImin3,1:ndim) xCC(ixIsmin1:ixIsmax1,ixIsmin2:ixIsmax2,ixIsmin3,3)=x(ixImin1,ixImin2,& ixImin3,3)-block%dx(ixImin1,ixImin2,ixImin3,3) xCC(ixImin1:ixImax1,ixIsmin2,ixIsmin3,1)=x(ixImin1:ixImax1,ixImin2,ixImin3,& 1) xCC(ixIsmin1,ixImin2:ixImax2,ixIsmin3,2)=x(ixImin1,ixImin2:ixImax2,ixImin3,& 2) xCC(ixIsmin1,ixIsmin2,ixImin3:ixImax3,3)=x(ixImin1,ixImin2,ixImin3:ixImax3,& 3) do idir=sdim,3 ixCmax1=ixOmax1;ixCmax2=ixOmax2;ixCmax3=ixOmax3; ixCmin1=ixOmin1-1+kr(idir,1);ixCmin2=ixOmin2-1+kr(idir,2) ixCmin3=ixOmin3-1+kr(idir,3); do idim1=1,ndim ! Get edge coordinates if (idim1/=idir) then xC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)=xCC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)+half*block%dx(ixCmin1:ixCmax1,ixCmin2:ixCmax2,& ixCmin3:ixCmax3,idim1) else xC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)=xCC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,idim1) end if end do ! Initialise vector potential at the edge call usr_init_vector_potential(ixIsmin1,ixIsmin2,ixIsmin3,ixIsmax1,& ixIsmax2,ixIsmax3, ixCmin1,ixCmin2,ixCmin3,ixCmax1,ixCmax2,ixCmax3,& xC, A(ixIsmin1:ixIsmax1,ixIsmin2:ixIsmax2,ixIsmin3:ixIsmax3,idir),& idir) A(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idir)=A(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idir)*block%dsC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,idir) end do ! Take the curl of the vector potential circ=zero ! Calculate circulation on each face do idim1=1,ndim ! Coordinate perpendicular to face ixCmax1=ixOmax1;ixCmax2=ixOmax2;ixCmax3=ixOmax3; ixCmin1=ixOmin1-kr(idim1,1);ixCmin2=ixOmin2-kr(idim1,2) ixCmin3=ixOmin3-kr(idim1,3); do idim2=1,ndim do idir=sdim,3 ! Direction of line integral if(lvc(idim1,idim2,idir)==0) cycle ! Assemble indices hxCmin1=ixCmin1-kr(idim2,1);hxCmin2=ixCmin2-kr(idim2,2) hxCmin3=ixCmin3-kr(idim2,3);hxCmax1=ixCmax1-kr(idim2,1) hxCmax2=ixCmax2-kr(idim2,2);hxCmax3=ixCmax3-kr(idim2,3); ! Add line integrals in direction idir circ(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)=circ(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)+lvc(idim1,idim2,idir)* (A(ixCmin1:ixCmax1,ixCmin2:ixCmax2,& ixCmin3:ixCmax3,idir)-A(hxCmin1:hxCmax1,hxCmin2:hxCmax2,& hxCmin3:hxCmax3,idir)) end do end do ! Divide by the area of the face to get B where(block%surfaceC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)==0) circ(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,idim1)=zero elsewhere circ(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)=circ(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1)/block%surfaceC(ixCmin1:ixCmax1,ixCmin2:ixCmax2,& ixCmin3:ixCmax3,idim1) end where ws(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,& idim1) = circ(ixCmin1:ixCmax1,ixCmin2:ixCmax2,ixCmin3:ixCmax3,idim1) end do end subroutine b_from_vector_potentialA