! field2d class for QuickPIC Open Source 1.0 ! update: 04/18/2016 module field2d_class use perrors_class use parallel_pipe_class use spect2d_class use field3d_class use ufield2d_class use ufield3d_class use fft2d_class use fpois2d_class use hdf5io_class implicit none private public :: field2d type field2d private ! state = (0,1) = current data is in (rs,ks) ! gcells = (0,1) = (no, yes) guard cell processing is performed class(spect2d), pointer, public :: sp => null() class(perrors), pointer, public :: err => null() class(parallel_pipe), pointer, public :: p => null() class(ufield2d), pointer :: rs => null(), ks => null() class(fft2d), pointer :: ft => null() class(fpois2d), pointer :: pt => null() integer :: state, gcells contains generic :: new => init_field2d generic :: del => end_field2d generic :: fftrk => fftrk_field2d generic :: fftkr => fftkr_field2d generic :: div => divf_field2d generic :: grad => gradf_field2d generic :: curl => curlf_field2d generic :: pot => potential_field2d generic :: smooth => smoothf_field2d generic :: elf => elfield_field2d generic :: bf => bfield_field2d generic :: bfqp => bfield_qp_field2d generic :: cg => copyguard_field2d generic :: ag => acopyguard_field2d generic :: psend => pipesend_field2d generic :: precv => piperecv_field2d generic :: cp => copyfrom generic :: ca => copyadd generic :: cb => copyto generic :: as => asc, asa generic :: add => sum1, sum2 generic :: sub => minus1, minus2 generic :: mult => multiply1, multiply2 generic :: wr => writehdf5_field2d procedure, private :: init_field2d, end_field2d procedure, private :: fftrk_field2d, fftkr_field2d, divf_field2d procedure, private :: gradf_field2d, curlf_field2d, potential_field2d procedure, private :: smoothf_field2d, elfield_field2d, bfield_field2d procedure, private :: bfield_qp_field2d, copyguard_field2d procedure, private :: acopyguard_field2d, pipesend_field2d procedure, private :: piperecv_field2d, asc, asa, sum1, minus1, multiply1 procedure, private :: writehdf5_field2d, multiply2, sum2, minus2 procedure, private :: copyfrom, copyto, copyadd procedure :: getstate, getgcells, getrs, getks end type character(len=10), save :: class = 'field2d:' character(len=128), save :: erstr contains ! subroutine init_field2d(this,pp,perr,psp,dim,fftflag,state,gcells) ! fftflag = (.false.,.true.) = (no,yes) initial ks, fft and poisson solver table implicit none class(field2d), intent(inout) :: this class(spect2d), intent(in), pointer :: psp class(perrors), intent(in), pointer :: perr class(parallel_pipe), intent(in), pointer :: pp integer, intent(in) :: dim logical, intent(in) :: fftflag integer, intent(in), optional :: state,gcells ! local data character(len=18), save :: sname = 'init_field2d:' integer :: nvpy,indx,indy,nd1,nd2 this%err => perr call this%err%werrfl2(class//sname//' started') this%sp => psp this%p => pp if (present(state)) then this%state = state else this%state = 0 endif if (present(gcells)) then this%gcells = gcells else this%gcells = 0 endif nvpy = pp%getlnvp() indx = psp%getindx() indy = psp%getindy() nd1 = 2**indx nd2 = 2**indy allocate(this%rs) call this%rs%new(pp,perr,psp,dim,0,0,nvpy) if (fftflag) then allocate(this%ks) call this%ks%new(pp,perr,psp,dim,1,nd1,nd2,0,nvpy) select case (psp%getpsolver()) case (1) this%ft => get_fft2table(pp,perr,psp,indx,indy) this%pt => get_pois2table(pp,perr,psp,ax=0.912871,ay=0.912871,affp=1.0) case default this%ft => get_fft2table(pp,perr,psp,indx,indy) this%pt => get_pois2table(pp,perr,psp,ax=0.912871,ay=0.912871,affp=1.0) end select endif call this%err%werrfl2(class//sname//' ended') end subroutine init_field2d ! subroutine end_field2d(this) implicit none class(field2d), intent(inout) :: this character(len=18), save :: sname = 'end_field2d:' call this%err%werrfl2(class//sname//' started') call this%rs%del() if (associated(this%ks)) call this%ks%del() deallocate(this%rs,this%ks) call this%err%werrfl2(class//sname//' ended') end subroutine end_field2d ! subroutine fftrk_field2d(this,kind) implicit none class(field2d), intent(inout) :: this integer, intent(in) :: kind character(len=18), save :: sname = 'fftrk_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 0) then call this%err%equit(class//sname//'data is in ks') return endif if (this%gcells == 0) call this%err%werrfl2('guard cell not processed') select case (kind) case (1) call this%ft%fsst(this%rs,this%ks,-1) case (2) call this%ft%fcct(this%rs,this%ks,-1) case (3) if (this%rs%getdim() /= 3) then call this%err%equit(class//sname//'wrong fft kind') return endif call this%ft%fs3t(this%rs,this%ks,-1) end select this%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine fftrk_field2d ! subroutine fftkr_field2d(this,kind) implicit none class(field2d), intent(inout) :: this integer, intent(in) :: kind character(len=18), save :: sname = 'fftkr_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif select case (kind) case (1) call this%ft%fsst(this%rs,this%ks,1) case (2) call this%ft%fcct(this%rs,this%ks,1) case (3) if (this%rs%getdim() /= 3) then call this%err%equit(class//sname//'wrong fft kind') return endif call this%ft%fs3t(this%rs,this%ks,1) end select this%state = 0 call this%rs%cg() call this%err%werrfl2(class//sname//' ended') end subroutine fftkr_field2d ! subroutine divf_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'divf_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%ft%divf(this%ks,that%ks) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine divf_field2d ! subroutine gradf_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'gradf_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%ft%gradf(this%ks,that%ks) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine gradf_field2d ! subroutine curlf_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'curlf_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%ft%curlf(this%ks,that%ks) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine curlf_field2d ! subroutine potential_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'potential_field2d:' real :: we call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%pt%potential(this%ks,that%ks,we) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine potential_field2d ! subroutine smoothf_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'smoothf_field2d:' real :: we call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%pt%smoothf(this%ks,that%ks) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine smoothf_field2d ! subroutine elfield_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'elfield_field2d:' real :: we call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%pt%elfield(this%ks,that%ks,we) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine elfield_field2d ! subroutine bfield_field2d(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'bfield_field2d:' real :: we call this%err%werrfl2(class//sname//' started') if (this%state /= 1) then call this%err%equit(class//sname//'data is in rs') return endif call this%pt%bfield(this%ks,that%ks,1.0,we) that%state = 1 call this%err%werrfl2(class//sname//' ended') end subroutine bfield_field2d ! subroutine bfield_qp_field2d(cu,dcu,amu,bxy,c,dex) implicit none class(field2d), intent(inout) :: cu,dcu,amu,bxy real, intent(in) :: c, dex character(len=18), save :: sname = 'bfield_qp_field2d:' real :: we call cu%err%werrfl2(class//sname//' started') if ((cu%state /= 1).or.(dcu%state /= 1).or.(amu%state /= 1)) then call cu%err%equit(class//sname//'data is in rs') return endif call cu%pt%bfield_qp(cu%ks,dcu%ks,amu%ks,bxy%ks,1.0,c,dex,we) bxy%state = 1 call cu%err%werrfl2(class//sname//' ended') end subroutine bfield_qp_field2d ! subroutine copyguard_field2d(this) implicit none class(field2d), intent(inout) :: this character(len=18), save :: sname = 'copyguard_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 0) then call this%err%equit(class//sname//'data is in ks') return endif call this%rs%cg() this%gcells = 1 this%state = 0 call this%err%werrfl2(class//sname//' ended') end subroutine copyguard_field2d ! subroutine acopyguard_field2d(this) implicit none class(field2d), intent(inout) :: this character(len=18), save :: sname = 'acopyguard_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state /= 0) then call this%err%equit(class//sname//'data is in ks') return endif call this%rs%ag() this%gcells = 1 this%state = 0 call this%err%werrfl2(class//sname//' ended') end subroutine acopyguard_field2d ! subroutine pipesend_field2d(this,stag,id) implicit none class(field2d), intent(inout) :: this integer, intent(in) :: stag integer, intent(inout) :: id character(len=18), save :: sname = 'pipesend_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state == 0) then call this%rs%psend(stag,id) else call this%ks%psend(stag,id) endif call this%err%werrfl2(class//sname//' ended') end subroutine pipesend_field2d ! subroutine piperecv_field2d(this,rtag) implicit none class(field2d), intent(inout) :: this integer, intent(in) :: rtag character(len=18), save :: sname = 'piperecv_field2d:' call this%err%werrfl2(class//sname//' started') if (this%state == 0) then call this%rs%precv(rtag) else call this%ks%precv(rtag) endif call this%err%werrfl2(class//sname//' ended') end subroutine piperecv_field2d ! subroutine asc(this,value) implicit none class(field2d), intent(inout) :: this real, intent(in) :: value character(len=18), save :: sname = 'asc:' call this%err%werrfl2(class//sname//' started') call this%rs%as(value) this%state = 0 this%gcells = 1 call this%err%werrfl2(class//sname//' ended') end subroutine asc ! subroutine copyto(this,that,lpos,sdim,ddim) implicit none class(field2d), intent(inout) :: this class(field3d), intent(in) :: that integer, intent(in) :: lpos integer, intent(in), dimension(:) :: sdim, ddim ! local data character(len=20), save :: sname = 'copyto:' class(ufield3d), pointer :: rs3d call this%err%werrfl2(class//sname//' started') rs3d => that%getrs() call rs3d%cp(this%rs,lpos,sdim,ddim) call this%err%werrfl2(class//sname//' ended') end subroutine copyto ! subroutine copyfrom(this,that,lpos,sdim,ddim) implicit none class(field2d), intent(inout) :: this class(field3d), intent(in) :: that integer, intent(in) :: lpos integer, intent(in), dimension(:) :: sdim, ddim ! local data character(len=20), save :: sname = 'copyfrom:' class(ufield3d), pointer :: rs3d call this%err%werrfl2(class//sname//' started') rs3d => that%getrs() call rs3d%cb(this%rs,lpos,sdim,ddim) this%gcells = 1 this%state = 0 call this%err%werrfl2(class//sname//' ended') end subroutine copyfrom ! subroutine copyadd(this,that,lpos,sdim,ddim) implicit none class(field2d), intent(inout) :: this class(field3d), intent(in) :: that integer, intent(in) :: lpos integer, intent(in), dimension(:) :: sdim, ddim ! local data character(len=20), save :: sname = 'copyadd:' class(ufield3d), pointer :: rs3d call this%err%werrfl2(class//sname//' started') rs3d => that%getrs() call rs3d%ca(this%rs,lpos,sdim,ddim) this%gcells = 1 this%state = 0 call this%err%werrfl2(class//sname//' ended') end subroutine copyadd ! subroutine asa(this,that) implicit none class(field2d), intent(inout) :: this,that character(len=18), save :: sname = 'asc:' call this%err%werrfl2(class//sname//' started') if (that%state == 0) then call this%rs%as(that%rs) else call this%ks%as(that%ks) endif this%state = that%state this%gcells = that%gcells call this%err%werrfl2(class//sname//' ended') end subroutine asa ! subroutine sum1(this,a1,a2) implicit none class(field2d), intent(inout) :: this class(field2d), intent(in) :: a1, a2 character(len=18), save :: sname = 'sum:' call this%err%werrfl2(class//sname//' started') if (a1%state /= a2%state) then call this%err%equit(class//sname//'states are different') return else if (a1%state == 0) then if (a1%gcells /= a2%gcells) then call this%err%equit(class//sname//'gcells are different') return else call this%rs%add(a1%rs,a2%rs) this%state = 0 this%gcells = a1%gcells endif else call this%ks%add(a1%ks,a2%ks) this%state = 1 endif call this%err%werrfl2(class//sname//' ended') end subroutine sum1 ! subroutine sum2(this,a1,a2,dim,dim1,dim2) implicit none class(field2d), intent(inout) :: this class(field2d), intent(in) :: a1, a2 integer, dimension(:), intent(in) :: dim, dim1, dim2 character(len=18), save :: sname = 'sum:' call this%err%werrfl2(class//sname//' started') if (a1%state /= a2%state) then call this%err%equit(class//sname//'states are different') return else if (a1%state == 0) then if (a1%gcells /= a2%gcells) then call this%err%equit(class//sname//'gcells are different') return else call this%rs%add(a1%rs,a2%rs,dim,dim1,dim2) this%state = 0 this%gcells = a1%gcells endif else call this%ks%add(a1%ks,a2%ks,dim,dim1,dim2) this%state = 1 endif call this%err%werrfl2(class//sname//' ended') end subroutine sum2 ! subroutine minus1(this,a1,a2) implicit none class(field2d), intent(inout) :: this class(field2d), intent(in) :: a1, a2 character(len=18), save :: sname = 'minus:' call this%err%werrfl2(class//sname//' started') if (a1%state /= a2%state) then call this%err%equit(class//sname//'states are different') return else if (a1%state == 0) then if (a1%gcells /= a2%gcells) then call this%err%equit(class//sname//'gcells are different') return else call this%rs%sub(a1%rs,a2%rs) this%state = 0 this%gcells = a1%gcells endif else call this%ks%sub(a1%ks,a2%ks) this%state = 1 endif call this%err%werrfl2(class//sname//' ended') end subroutine minus1 ! subroutine minus2(this,a1,a2,dim,dim1,dim2) implicit none class(field2d), intent(inout) :: this class(field2d), intent(in) :: a1, a2 integer, dimension(:), intent(in) :: dim, dim1, dim2 character(len=18), save :: sname = 'minus:' call this%err%werrfl2(class//sname//' started') if (a1%state /= a2%state) then call this%err%equit(class//sname//'states are different') return else if (a1%state == 0) then if (a1%gcells /= a2%gcells) then call this%err%equit(class//sname//'gcells are different') return else call this%rs%sub(a1%rs,a2%rs,dim,dim1,dim2) this%state = 0 this%gcells = a1%gcells endif else call this%ks%sub(a1%ks,a2%ks,dim,dim1,dim2) this%state = 1 endif call this%err%werrfl2(class//sname//' ended') end subroutine minus2 ! subroutine multiply1(this,a1,value) implicit none class(field2d), intent(inout) :: this class(field2d), intent(in) :: a1 real, intent(in) :: value character(len=18), save :: sname = 'multiply1:' call this%err%werrfl2(class//sname//' started') if (a1%state == 0) then call this%rs%mult(a1%rs,value) this%state = 0 this%gcells = a1%gcells else call this%ks%mult(a1%ks,value) this%state = 1 endif call this%err%werrfl2(class//sname//' ended') end subroutine multiply1 ! subroutine multiply2(this,a1,dim,dim1,value) implicit none class(field2d), intent(inout) :: this class(field2d), intent(in) :: a1 integer, dimension(:), intent(in) :: dim,dim1 real, dimension(:), intent(in) :: value character(len=18), save :: sname = 'multiply2:' call this%err%werrfl2(class//sname//' started') if (a1%state == 0) then call this%rs%mult(a1%rs,dim,dim1,value) this%state = 0 this%gcells = a1%gcells else call this%ks%mult(a1%ks,dim,dim1,value) this%state = 1 endif call this%err%werrfl2(class//sname//' ended') end subroutine multiply2 ! subroutine writehdf5_field2d(this,file,dim) implicit none class(field2d), intent(inout) :: this class(hdf5file), intent(in) :: file integer, intent(in) :: dim character(len=20), save :: sname = 'writehdf5_field2d:' call this%err%werrfl2(class//sname//' started') call this%rs%wr(file,dim) call this%err%werrfl2(class//sname//' ended') end subroutine writehdf5_field2d ! function getstate(this) implicit none class(field2d), intent(in) :: this integer :: getstate getstate = this%state end function getstate ! function getgcells(this) implicit none class(field2d), intent(in) :: this integer :: getgcells getgcells = this%gcells end function getgcells ! function getrs(this) implicit none class(field2d), intent(in) :: this class(ufield2d), pointer :: getrs getrs => this%rs end function getrs ! function getks(this) implicit none class(field2d), intent(in) :: this class(ufield2d), pointer :: getks getks => this%ks end function getks ! end module field2d_class