!------------------------------------------------------------------------- ! Subroutine : ppm_gmm_extend !------------------------------------------------------------------------- ! Parallel Particle Mesh Library (PPM) ! ETH Zurich ! CH-8092 Zurich, Switzerland !------------------------------------------------------------------------- #if __KICKOFF == __YES #if __DIM == __2D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_ksca_s(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_ksca_d(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_kvec_s(ivalue,fdata,udata,lda,tol, & & width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_kvec_d(ivalue,fdata,udata,lda,tol, & & width,order,info,chi,MaxIter) #endif #endif #elif __DIM == __3D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_ksca_s(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_ksca_d(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_kvec_s(ivalue,fdata,udata,lda, & & tol,width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_kvec_d(ivalue,fdata,udata,lda, & & tol,width,order,info,chi,MaxIter) #endif #endif #endif #elif __KICKOFF == __NO #if __DIM == __2D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_tsca_s(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_tsca_d(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_tvec_s(ivalue,fdata,udata,lda,tol, & & width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_2d_tvec_d(ivalue,fdata,udata,lda,tol, & & width,order,info,chi,MaxIter) #endif #endif #elif __DIM == __3D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_tsca_s(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_tsca_d(ivalue,fdata,udata,tol, & & width,order,info,chi,MaxIter) #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_tvec_s(ivalue,fdata,udata,lda, & & tol,width,order,info,chi,MaxIter) #elif __KIND == __DOUBLE_PRECISION SUBROUTINE ppm_gmm_extend_3d_tvec_d(ivalue,fdata,udata,lda, & & tol,width,order,info,chi,MaxIter) #endif #endif #endif #endif !!! This routine extends a function defined on the interface to the whole !!! band on which the level function is defined. The extension is done !!! such that the gradient of the function is perpendicular to the !!! gradient of the level function. ppm_gmm_init must be called BEFORE !!! this routine is invoked. !------------------------------------------------------------------------- ! Includes !------------------------------------------------------------------------- #include "ppm_define.h" !------------------------------------------------------------------------- ! Modules !------------------------------------------------------------------------- USE ppm_module_data USE ppm_module_data_mesh USE ppm_module_data_gmm USE ppm_module_gmm_init USE ppm_module_gmm_cpt USE ppm_module_gmm_march USE ppm_module_gmm_finalize USE ppm_module_substart USE ppm_module_substop USE ppm_module_error USE ppm_module_alloc USE ppm_module_typedef IMPLICIT NONE #if __KIND == __SINGLE_PRECISION | __KIND == __SINGLE_PRECISION_COMPLEX INTEGER, PARAMETER :: MK = ppm_kind_single #else INTEGER, PARAMETER :: MK = ppm_kind_double #endif !------------------------------------------------------------------------- ! Arguments !------------------------------------------------------------------------- #if __DIM == __2D #if __KICKOFF == __YES #if __KIND == __SINGLE_PRECISION INTERFACE FUNCTION ivalue(x,y,info) REAL(KIND(1.0E0)), INTENT(IN) :: x,y REAL(KIND(1.0E0)) :: ivalue INTEGER, INTENT(OUT) :: info END FUNCTION ivalue END INTERFACE #elif __KIND == __DOUBLE_PRECISION INTERFACE FUNCTION ivalue(x,y,info) REAL(KIND(1.0D0)), INTENT(IN) :: x,y REAL(KIND(1.0D0)) :: ivalue INTEGER, INTENT(OUT) :: info END FUNCTION ivalue END INTERFACE #endif !!! Function pointer to the function computing the value of the function !!! on the interface: (F) ivalue(x,y[,z]) !!! The function may assume that the point (x,y[,z]) is on the interface. #else REAL(MK) , INTENT(IN ) :: ivalue !!! A (F) scalar value defining a cutoff. Points closer to the interface !!! than this cutoff will be kept to initialize the marching. The cpt !!! is skipped in this case. #endif #if __TYPE == __SFIELD REAL(MK), DIMENSION(:,:,:) , POINTER :: udata !!! Field of the function to be extended, defined in the same narrow !!! band as the level function. Values outside this band are set to !!! HUGE. This has to be allocated to proper size incl. ghost layers of !!! size order! If ivalue is a function pointer, udata will be !!! completely replaced. If ivalue is a scalar, the points closer to !!! the interface than this scalar are kept unchanged. Can be a vector !!! or a scalar field. If vector, lda must be given. #elif __TYPE == __VFIELD REAL(MK), DIMENSION(:,:,:,:) , POINTER :: udata !!! Field of the function to be extended, defined in the same narrow !!! band as the level function. Values outside this band are set to !!! HUGE. This has to be allocated to proper size incl. ghost layers of !!! size order! If ivalue is a function pointer, udata will be !!! completely replaced. If ivalue is a scalar, the points closer to !!! the interface than this scalar are kept unchanged. Can be a vector !!! or a scalar field. If vector, lda must be given. INTEGER , INTENT(IN ) :: lda !!! Only present for vector udata. Gives the length of the leading !!! dimension of udata. All elements will be equally extended. #endif REAL(MK), DIMENSION(:,:,:) , POINTER :: fdata !!! Level function data. Needs to be defined in a narrow band of !!! specific width around the interface. The zero level is interpreted !!! to be the interface. Always a scalar field. THIS NEEDS TO BE !!! PROPERLY ALLOCATED ON INPUT, INCLUDING GHOST LAYERS OF SIZE order. REAL(MK), DIMENSION(:,:,:,:) , INTENT(IN),OPTIONAL:: chi !!! rank 5 (3d) or rank 4 (2d) field specifying the positions !!! of the grid nodes. 1st index: 1..ppm_dim, then i,j,[k],isub. !!! OPTIONAL. Uniform grid is assumed if absent. Ghostlayers of size !!! >=1 must be pre-filled. #elif __DIM == __3D #if __KICKOFF == __YES #if __KIND == __SINGLE_PRECISION INTERFACE FUNCTION ivalue(x,y,z,info) REAL(KIND(1.0E0)), INTENT(IN) :: x,y,z REAL(KIND(1.0E0)) :: ivalue INTEGER, INTENT(OUT) :: info END FUNCTION ivalue END INTERFACE #elif __KIND == __DOUBLE_PRECISION INTERFACE FUNCTION ivalue(x,y,z,info) REAL(KIND(1.0D0)), INTENT(IN) :: x,y,z REAL(KIND(1.0D0)) :: ivalue INTEGER, INTENT(OUT) :: info END FUNCTION ivalue END INTERFACE #endif !!! Function pointer to the function computing the value of the function !!! on the interface: (F) ivalue(x,y[,z]) !!! The function may assume that the point (x,y[,z]) is on the interface. #else REAL(MK) , INTENT(IN ) :: ivalue !!! A (F) scalar value defining a cutoff. Points closer to the interface !!! than this cutoff will be kept to initialize the marching. The cpt !!! is skipped in this case. #endif #if __TYPE == __SFIELD REAL(MK), DIMENSION(:,:,:,:) , POINTER :: udata !!! Field of the function to be extended, defined in the same narrow !!! band as the level function. Values outside this band are set to !!! HUGE. This has to be allocated to proper size incl. ghost layers of !!! size order! If ivalue is a function pointer, udata will be !!! completely replaced. If ivalue is a scalar, the points closer to !!! the interface than this scalar are kept unchanged. Can be a vector !!! or a scalar field. If vector, lda must be given. #elif __TYPE == __VFIELD REAL(MK), DIMENSION(:,:,:,:,:) , POINTER :: udata !!! Field of the function to be extended, defined in the same narrow !!! band as the level function. Values outside this band are set to !!! HUGE. This has to be allocated to proper size incl. ghost layers of !!! size order! If ivalue is a function pointer, udata will be !!! completely replaced. If ivalue is a scalar, the points closer to !!! the interface than this scalar are kept unchanged. Can be a vector !!! or a scalar field. If vector, lda must be given. INTEGER , INTENT(IN ) :: lda !!! Only present for vector udata. Gives the length of the leading !!! dimension of udata. All elements will be equally extended. #endif REAL(MK), DIMENSION(:,:,:,:) , POINTER :: fdata !!! Level function data. Needs to be defined in a narrow band of !!! specific width around the interface. The zero level is interpreted !!! to be the interface. Always a scalar field. THIS NEEDS TO BE !!! PROPERLY ALLOCATED ON INPUT, INCLUDING GHOST LAYERS OF SIZE order. REAL(MK), DIMENSION(:,:,:,:,:) , INTENT(IN),OPTIONAL:: chi !!! rank 5 (3d) or rank 4 (2d) field specifying the positions !!! of the grid nodes. 1st index: 1..ppm_dim, then i,j,[k],isub. !!! OPTIONAL. Uniform grid is assumed if absent. Ghostlayers of size !!! >=1 must be pre-filled. #endif INTEGER , INTENT(IN ) :: order !!! Order of the method to be used. One of !!! !!! *ppm_param_order_1 !!! *ppm_param_order_2 !!! *ppm_param_order_3 REAL(MK) , INTENT(IN ) :: tol !!! Relative tolerance for the determined distance to the interface. 1E-3 !!! is a good choice. The tolerance is in multiples of grid spacings. REAL(MK) , INTENT(IN ) :: width !!! Width of the narrow band to be produced on each side of !!! the interface. INTEGER , INTENT( OUT) :: info !!! Return status, 0 upon success INTEGER , OPTIONAL , INTENT(IN ) :: MaxIter !!! OPTIONAL argument specifying the maximum number of allowed !!! iterations. This can be useful since a cyclic dependency in the GMM !!! algorithms could cause infinite loops. In each iteration at least one !!! point is computed. !------------------------------------------------------------------------- ! Local variables !------------------------------------------------------------------------- INTEGER :: isub,npts,MaxIt INTEGER :: i,j,k,p INTEGER :: iopt,jsub,ida INTEGER , DIMENSION(4) :: ldl,ldu REAL(MK) :: t0,x,y,z,big LOGICAL :: lok REAL(MK), DIMENSION(:,:), POINTER :: closest TYPE(ppm_t_topo), POINTER :: topo TYPE(ppm_t_equi_mesh), POINTER :: mesh #if __TYPE == __VFIELD #if __DIM == __2D REAL(MK), DIMENSION(:,:,: ), POINTER :: ext_wrk #elif __DIM == __3D REAL(MK), DIMENSION(:,:,:,:), POINTER :: ext_wrk #endif #endif !------------------------------------------------------------------------- ! Initialise !------------------------------------------------------------------------- CALL substart('ppm_gmm_extend',t0,info) big = HUGE(big) topo => ppm_topo(gmm_topoid)%t mesh => topo%mesh(gmm_meshid) !------------------------------------------------------------------------- ! Set pointers !------------------------------------------------------------------------- #if __KIND == __SINGLE_PRECISION closest => gmm_clos2 #elif __KIND == __DOUBLE_PRECISION closest => gmm_clod2 #endif #if __TYPE == __VFIELD #if __DIM == __2D #if __KIND == __SINGLE_PRECISION ext_wrk => ext_wrk_2ds #elif __KIND == __DOUBLE_PRECISION ext_wrk => ext_wrk_2dd #endif #elif __DIM == __3D #if __KIND == __SINGLE_PRECISION ext_wrk => ext_wrk_3ds #elif __KIND == __DOUBLE_PRECISION ext_wrk => ext_wrk_3dd #endif #endif #endif !------------------------------------------------------------------------- ! Check arguments !------------------------------------------------------------------------- IF (ppm_debug .GT. 0) THEN IF (.NOT. ppm_initialized) THEN info = ppm_error_error CALL ppm_error(ppm_err_ppm_noinit,'ppm_gmm_extend', & & 'Please call ppm_init first!',__LINE__,info) GOTO 9999 ENDIF IF (tol .LE. 0.0_MK) THEN info = ppm_error_error CALL ppm_error(ppm_err_argument,'ppm_gmm_extend', & & 'tolerance must be >0!',__LINE__,info) GOTO 9999 ENDIF IF (width .LE. 0.0_MK) THEN info = ppm_error_error CALL ppm_error(ppm_err_argument,'ppm_gmm_extend', & & 'width must be >0!',__LINE__,info) GOTO 9999 ENDIF #if __TYPE == __VFIELD IF (lda .LT. 1) THEN info = ppm_error_error CALL ppm_error(ppm_err_argument,'ppm_gmm_extend', & & 'lda must be >=1 for vector data',__LINE__,info) GOTO 9999 ENDIF #endif ENDIF ! ppm_debug for argument check #if __KICKOFF == __YES !------------------------------------------------------------------------- ! Closest point transform on fdata !------------------------------------------------------------------------- IF (PRESENT(chi)) THEN CALL ppm_gmm_cpt(fdata,tol,npts,iptstmp2,closest,info,chi) ELSE CALL ppm_gmm_cpt(fdata,tol,npts,iptstmp2,closest,info) ENDIF IF (info .NE. ppm_param_success) THEN info = ppm_error_error CALL ppm_error(ppm_err_sub_failed,'ppm_gmm_extend', & & 'Closest point transform failed.',__LINE__,info) GOTO 9999 ENDIF !------------------------------------------------------------------------- ! Allocate udata !------------------------------------------------------------------------- ! iopt = ppm_param_alloc_fit ! ldl(1) = 1 - ghostsize(1) ! ldl(2) = 1 - ghostsize(2) ! ldl(3) = 1 - ghostsize(3) ! ldl(4) = 1 ! ldu(1) = maxxhi + ghostsize(1) ! ldu(2) = maxyhi + ghostsize(2) ! ldu(3) = maxzhi + ghostsize(3) ! ldu(4) = topo%nsublist ! CALL ppm_alloc(udata,ldl,ldu,iopt,info) ! IF (info .NE. ppm_param_success) THEN ! info = ppm_error_fatal ! CALL ppm_error(ppm_err_alloc,'ppm_gmm_extend', & ! & 'function data UDATA',__LINE__,info) ! GOTO 9999 ! ENDIF udata = HUGE(x) !------------------------------------------------------------------------- ! Assign each point the value of its closest point on the ! interface. !------------------------------------------------------------------------- #if __DIM == __3D DO p=1,npts i = iptstmp2(1,p) j = iptstmp2(2,p) k = iptstmp2(3,p) isub = iptstmp2(4,p) x = closest(1,p) y = closest(2,p) z = closest(3,p) #if __TYPE == __SFIELD udata(i,j,k,isub) = ivalue(x,y,z,info) #elif __TYPE == __VFIELD udata(1,i,j,k,isub) = ivalue(x,y,z,info) DO ida=2,lda udata(ida,i,j,k,isub) = udata(1,i,j,k,isub) ENDDO #endif ENDDO #elif __DIM == __2D DO p=1,npts i = iptstmp2(1,p) j = iptstmp2(2,p) isub = iptstmp2(3,p) x = closest(1,p) y = closest(2,p) #if __TYPE == __SFIELD udata(i,j,isub) = ivalue(x,y,info) #elif __TYPE == __VFIELD udata(1,i,j,isub) = ivalue(x,y,info) DO ida=2,lda udata(ida,i,j,isub) = udata(1,i,j,isub) ENDDO #endif ENDDO #endif !------------------------------------------------------------------------- ! Deallocate !------------------------------------------------------------------------- iopt = ppm_param_dealloc CALL ppm_alloc(closest,ldu,iopt,info) IF (info .NE. ppm_param_success) THEN info = ppm_error_error CALL ppm_error(ppm_err_dealloc,'ppm_gmm_extend', & & 'closest points locations CLOSEST',__LINE__,info) ENDIF #if __KIND == __SINGLE_PRECISION NULLIFY(gmm_clos2) #elif __KIND == __DOUBLE_PRECISION NULLIFY(gmm_clod2) #endif CALL ppm_alloc(iptstmp2,ldu,iopt,info) IF (info .NE. ppm_param_success) THEN info = ppm_error_error CALL ppm_error(ppm_err_dealloc,'ppm_gmm_extend', & & 'close mesh points IPTS',__LINE__,info) ENDIF #elif __KICKOFF == __NO !------------------------------------------------------------------------- ! Add ghost layers to field if needed !------------------------------------------------------------------------- ! iopt = ppm_param_alloc_grow_preserve ! ldl(1) = 1 - ghostsize(1) ! ldl(2) = 1 - ghostsize(2) ! ldl(3) = 1 - ghostsize(3) ! ldl(4) = 1 ! ldu(1) = maxxhi + ghostsize(1) ! ldu(2) = maxyhi + ghostsize(2) ! ldu(3) = maxzhi + ghostsize(3) ! ldu(4) = topo%nsublist ! CALL ppm_alloc(udata,ldu,iopt,info) ! IF (info .NE. ppm_param_success) THEN ! info = ppm_error_fatal ! CALL ppm_error(ppm_err_alloc,'ppm_gmm_extend', & ! & 'function data UDATA',__LINE__,info) ! GOTO 9999 ! ENDIF !------------------------------------------------------------------------- ! Nuke points farther from the interface than ivalue !------------------------------------------------------------------------- #if __DIM == __3D DO isub=1,topo%nsublist jsub = topo%isublist(isub) DO k=1,mesh%nnodes(3,jsub) DO j=1,mesh%nnodes(2,jsub) DO i=1,mesh%nnodes(1,jsub) IF (ABS(fdata(i,j,k,isub)) .GT. ivalue) THEN #if __TYPE == __VFIELD DO ida=1,lda udata(ida,i,j,k,isub) = big ENDDO #elif __TYPE == __SFIELD udata(i,j,k,isub) = big #endif ENDIF ENDDO ENDDO ENDDO ENDDO #elif __DIM == __2D DO isub=1,topo%nsublist jsub = topo%isublist(isub) DO j=1,mesh%nnodes(2,jsub) DO i=1,mesh%nnodes(1,jsub) IF (ABS(fdata(i,j,isub)) .GT. ivalue) THEN #if __TYPE == __VFIELD DO ida=1,lda udata(ida,i,j,isub) = big ENDDO #elif __TYPE == __SFIELD udata(i,j,isub) = big #endif ENDIF ENDDO ENDDO ENDDO #endif #endif !------------------------------------------------------------------------- ! Check the maximum number of allowed iterations !------------------------------------------------------------------------- IF (PRESENT(MaxIter)) THEN MaxIt = MaxIter ELSE MaxIt = HUGE(MaxIt) ENDIF !------------------------------------------------------------------------- ! Marching udata !------------------------------------------------------------------------- #if __TYPE == __VFIELD !------------------------------------------------------------------------- ! Allocate work array !------------------------------------------------------------------------- iopt = ppm_param_alloc_fit ldl(1) = LBOUND(udata,2) ldl(2) = LBOUND(udata,3) #if __DIM == __3D ldl(3) = LBOUND(udata,4) #endif ldl(4) = 1 ldu(1) = UBOUND(udata,2) ldu(2) = UBOUND(udata,3) #if __DIM == __3D ldu(3) = UBOUND(udata,4) #endif ldu(4) = topo%nsublist CALL ppm_alloc(ext_wrk,ldl,ldu,iopt,info) IF (info .NE. ppm_param_success) THEN info = ppm_error_fatal CALL ppm_error(ppm_err_alloc,'ppm_gmm_extend', & & 'work memory EXT_WRK',__LINE__,info) GOTO 9999 ENDIF !------------------------------------------------------------------------- ! Do each vector dimension separately using the work memory !------------------------------------------------------------------------- DO ida=1,lda #if __DIM == __3D DO isub=1,ldu(4) DO k=ldl(3),ldu(3) DO j=ldl(2),ldu(2) DO i=ldl(1),ldu(1) ext_wrk(i,j,k,isub) = udata(ida,i,j,k,isub) ENDDO ENDDO ENDDO ENDDO #elif __DIM == __2D DO isub=1,ldu(4) DO j=ldl(2),ldu(2) DO i=ldl(1),ldu(1) ext_wrk(i,j,isub) = udata(ida,i,j,isub) ENDDO ENDDO ENDDO #endif !--------------------------------------------------------------------- ! March !--------------------------------------------------------------------- IF (PRESENT(chi)) THEN CALL ppm_gmm_march(width,order,fdata,0.0_MK,MaxIt,info, & & udata=ext_wrk,chi=chi) ELSE CALL ppm_gmm_march(width,order,fdata,0.0_MK,MaxIt,info, & & udata=ext_wrk) ENDIF IF (info .NE. ppm_param_success) THEN info = ppm_error_error CALL ppm_error(ppm_err_sub_failed,'ppm_gmm_extend', & & 'Marching GMM failed.',__LINE__,info) GOTO 9999 ENDIF !--------------------------------------------------------------------- ! The ghostsize might have changed in the marching, depending on ! the order of the marching algorithm. !--------------------------------------------------------------------- ldl(1) = MAX(ldl(1),LBOUND(ext_wrk,1)) ldl(2) = MAX(ldl(2),LBOUND(ext_wrk,2)) #if __DIM == __3D ldl(3) = MAX(ldl(3),LBOUND(ext_wrk,3)) #endif ldu(1) = MIN(ldu(1),UBOUND(ext_wrk,1)) ldu(2) = MIN(ldu(2),UBOUND(ext_wrk,2)) #if __DIM == __3D ldu(3) = MIN(ldu(3),UBOUND(ext_wrk,3)) #endif !--------------------------------------------------------------------- ! Copy results back !--------------------------------------------------------------------- #if __DIM == __3D DO isub=1,ldu(4) DO k=ldl(3),ldu(3) DO j=ldl(2),ldu(2) DO i=ldl(1),ldu(1) udata(ida,i,j,k,isub) = ext_wrk(i,j,k,isub) ENDDO ENDDO ENDDO ENDDO #elif __DIM == __2D DO isub=1,ldu(4) DO j=ldl(2),ldu(2) DO i=ldl(1),ldu(1) udata(ida,i,j,isub) = ext_wrk(i,j,isub) ENDDO ENDDO ENDDO #endif ENDDO ! ida !------------------------------------------------------------------------- ! Free work memory !------------------------------------------------------------------------- iopt = ppm_param_dealloc CALL ppm_alloc(ext_wrk,ldl,ldu,iopt,info) IF (info .NE. ppm_param_success) THEN info = ppm_error_error CALL ppm_error(ppm_err_dealloc,'ppm_gmm_extend', & & 'work memory EXT_WRK',__LINE__,info) ENDIF #if __TYPE == __VFIELD #if __DIM == __2D #if __KIND == __SINGLE_PRECISION NULLIFY(ext_wrk_2ds) #elif __KIND == __DOUBLE_PRECISION NULLIFY(ext_wrk_2dd) #endif #elif __DIM == __3D #if __KIND == __SINGLE_PRECISION NULLIFY(ext_wrk_3ds) #elif __KIND == __DOUBLE_PRECISION NULLIFY(ext_wrk_3dd) #endif #endif #endif #elif __TYPE == __SFIELD !------------------------------------------------------------------------- ! Do scalar marching directly !------------------------------------------------------------------------- IF (PRESENT(chi)) THEN CALL ppm_gmm_march(width,order,fdata,0.0_MK,MaxIt,info, & & udata=udata,chi=chi) ELSE CALL ppm_gmm_march(width,order,fdata,0.0_MK,MaxIt,info,udata=udata) ENDIF IF (info .NE. ppm_param_success) THEN info = ppm_error_error CALL ppm_error(ppm_err_sub_failed,'ppm_gmm_extend', & & 'Marching GMM failed.',__LINE__,info) GOTO 9999 ENDIF #endif !------------------------------------------------------------------------- ! Return !------------------------------------------------------------------------- 9999 CONTINUE CALL substop('ppm_gmm_extend',t0,info) RETURN #if __KICKOFF == __YES #if __DIM == __2D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_ksca_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_ksca_d #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_kvec_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_kvec_d #endif #endif #elif __DIM == __3D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_ksca_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_ksca_d #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_kvec_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_kvec_d #endif #endif #endif #elif __KICKOFF == __NO #if __DIM == __2D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_tsca_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_tsca_d #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_tvec_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_2d_tvec_d #endif #endif #elif __DIM == __3D #if __TYPE == __SFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_tsca_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_tsca_d #endif #elif __TYPE == __VFIELD #if __KIND == __SINGLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_tvec_s #elif __KIND == __DOUBLE_PRECISION END SUBROUTINE ppm_gmm_extend_3d_tvec_d #endif #endif #endif #endif