b_from_vector_potentialA Subroutine

public 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)

Uses

  • proc~~b_from_vector_potentiala~~UsesGraph proc~b_from_vector_potentiala b_from_vector_potentialA module~mod_comm_lib mod_comm_lib proc~b_from_vector_potentiala->module~mod_comm_lib module~mod_global_parameters mod_global_parameters proc~b_from_vector_potentiala->module~mod_global_parameters module~mod_usr_methods mod_usr_methods proc~b_from_vector_potentiala->module~mod_usr_methods module~mod_basic_types mod_basic_types module~mod_global_parameters->module~mod_basic_types module~mod_connectivity mod_connectivity module~mod_global_parameters->module~mod_connectivity module~mod_constants mod_constants module~mod_global_parameters->module~mod_constants module~mod_physicaldata mod_physicaldata module~mod_global_parameters->module~mod_physicaldata module~mod_variables mod_variables module~mod_global_parameters->module~mod_variables mpi mpi module~mod_global_parameters->mpi module~mod_variables->module~mod_basic_types

calculate magnetic field from vector potential A at cell edges

Arguments

Type IntentOptional 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)

Calls

proc~~b_from_vector_potentiala~~CallsGraph proc~b_from_vector_potentiala b_from_vector_potentialA proc~mpistop mpistop proc~b_from_vector_potentiala->proc~mpistop mpi_abort mpi_abort proc~mpistop->mpi_abort

Called by

proc~~b_from_vector_potentiala~~CalledByGraph proc~b_from_vector_potentiala b_from_vector_potentialA proc~fake_update fake_update proc~fake_update->proc~b_from_vector_potentiala proc~fake_advance fake_advance proc~fake_advance->proc~fake_update proc~recalculateb recalculateB proc~recalculateb->proc~fake_advance proc~improve_initial_condition improve_initial_condition proc~improve_initial_condition->proc~recalculateb proc~main main proc~main->proc~improve_initial_condition program~agile agile program~agile->proc~main

Source Code

  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