diff --git a/Makefile b/Makefile index a0e17d3bcbbe76c7acc967c5bf3b287ed0353268..8e7138932da210fd67c488457d1b89b6871eb009 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,8 @@ gdebug: compile # test SVD test_svd: F90 = mpif90 -test_svd: F90FLAGS = -DTEST_SVD -g -traceback -ftrapuv -warn all -debug all +# test_svd: F90FLAGS = -DTEST_SVD -g -traceback -ftrapuv -warn all -debug all +test_svd: F90FLAGS = -DTEST_SVD -O3 test_svd: EXEC = $(BINDIR)/gyacomo23_test_svd test_svd: dirs src/srcinfo.h test_svd: dirs src/srcinfo.h @@ -123,7 +124,7 @@ $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o $(OBJDIR)/DLRA_mod.o $(OBJDIR)/auxval.o : src/auxval.F90 \ $(OBJDIR)/fourier_mod.o $(OBJDIR)/memory.o $(OBJDIR)/model_mod.o \ $(OBJDIR)/geometry_mod.o $(OBJDIR)/grid_mod.o $(OBJDIR)/numerics_mod.o \ - $(OBJDIR)/parallel_mod.o $(OBJDIR)/processing_mod.o + $(OBJDIR)/parallel_mod.o $(OBJDIR)/processing_mod.o $(OBJDIR)/DLRA_mod.o $(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/auxval.F90 -o $@ $(OBJDIR)/basic_mod.o : src/basic_mod.F90 \ @@ -309,5 +310,6 @@ $(OBJDIR)/time_integration_mod.o $(OBJDIR)/utility_mod.o $(OBJDIR)/DLRA_mod.o $(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/utility_mod.F90 -o $@ $(OBJDIR)/DLRA_mod.o : src/DLRA_mod.F90 \ - $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o + $(OBJDIR)/basic_mod.o $(OBJDIR)/prec_const_mod.o $(OBJDIR)/fields_mod.o $(OBJDIR)/grid_mod.o \ + $(OBJDIR)/time_integration_mod.o $(F90) -c $(F90FLAGS) $(FPPFLAGS) $(EXTMOD) $(EXTINC) src/DLRA_mod.F90 -o $@ diff --git a/src/DLRA_mod.F90 b/src/DLRA_mod.F90 index c6a39166d6211510812a6a131e4116afda2011ee..3be00e962646d763d5c69da1a11186c1136fa329 100644 --- a/src/DLRA_mod.F90 +++ b/src/DLRA_mod.F90 @@ -1,239 +1,243 @@ module DLRA - USE prec_const - implicit none - - PUBLIC :: filter_singular_value_ky_pj, test_SVD - - CONTAINS - - SUBROUTINE filter_singular_value_ky_pj(nsv,array_ky_pj) - IMPLICIT NONE - ! ARGUMENTS - INTEGER, INTENT(IN) :: nsv ! number of singular values to keep - COMPLEX(xp), DIMENSION(:,:), INTENT(INOUT) :: array_ky_pj ! Array to filter - ! - - ! Singular value decomposition - ! CALL SVD(array_ky_pj,singular_values) - END SUBROUTINE - - SUBROUTINE test_svd + USE prec_const + USE parallel + implicit none #ifdef TEST_SVD - ! Program to perform Singular Value Decomposition (SVD) - ! using LAPACK library - - ! Specify the dimensions of the input matrix A - INTEGER, PARAMETER :: m = 3, n = 2 - - ! Declare the input matrix A - COMPLEX, DIMENSION(m,n) :: A - - ! OUTPUT - COMPLEX, DIMENSION(m,m) :: U - REAL, DIMENSION(MIN(m,n)) :: S - COMPLEX, DIMENSION(n,n) :: VT - - ! local variables - INTEGER :: lda, ldu, ldvt, info, lwork, i, j - COMPLEX, DIMENSION(:), ALLOCATABLE :: work - REAL, DIMENSION(:), ALLOCATABLE :: rwork - - ! Set the leading dimensions for the input and output arrays - lda = MAX(1, m) - ldu = MAX(1, m) - ldvt = MAX(1, n) - - ! Define the input matrix A - A = RESHAPE((/ (1.0,0.1), (2.0,0.2), (3.0,0.3), (4.0,0.4), (5.0,0.5), (6.0,0.6) /), SHAPE(A)) - - ! Print the input matrix A - WRITE(*,*) 'Input matrix A = ' - DO i = 1, m - WRITE(*,*) ('(',REAL(A(i,j)), AIMAG(A(i,j)),')', j=1,n) - END DO - - ALLOCATE(work(5*n), rwork(5*n)) - ! Compute the optimal workspace size - lwork = -1 - CALL CGESVD('A', 'A', m, n, A, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) - - ! Allocate memory for the workspace arrays - lwork = CEILING(REAL(work(1)), KIND=SELECTED_REAL_KIND(1, 6)) - - ! Compute the SVD of A using the LAPACK subroutine CGESVD - CALL CGESVD('A', 'A', m, n, A, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) - - ! Print the results - WRITE(*,*) 'U = ' - DO i = 1, m - WRITE(*,*) ('(',REAL(U(i,j)), AIMAG(U(i,j)),')', j=1,m) - END DO - WRITE(*,*) - WRITE(*,*) 'S = ' - WRITE(*,'(2F8.3)') (S(i), i=1,n) - WRITE(*,*) - WRITE(*,*) 'VT = ' - DO i = 1, n - WRITE(*,*) ('(',REAL(VT(i,j)), AIMAG(VT(i,j)),')', j=1,n) - END DO - - ! Reconstruct A from its SVD - A = MATMUL(U, MATMUL(diagmat(S,m,n), VT)) - - ! Print the reconstructed matrix A - WRITE(*,*) 'Reconstructed matrix A = ' - DO i = 1, m - WRITE(*,*) ('(',REAL(A(i,j)), AIMAG(A(i,j)),')', j=1,n) - END DO - stop + ! LOCAL VARIABLES + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: A_buff,Bf,Br ! buffer and full/reduced rebuilt matrices + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: U ! basis + REAL(xp), DIMENSION(:), ALLOCATABLE :: Sf, Sr ! full and reduced singular values + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: VT ! basis + INTEGER :: lda, ldu, ldvt, info, lwork, i, m,n, nsv_filter + COMPLEX(xp), DIMENSION(:), ALLOCATABLE :: work + REAL(xp), DIMENSION(:), ALLOCATABLE :: rwork + PUBLIC :: init_DLRA, filter_sv_moments_ky_pj, test_SVD + +CONTAINS + + SUBROUTINE init_DLRA(m_,n_) + USE basic + IMPLICIT NONE + ! ARGUMENTS + INTEGER, INTENT(IN) :: m_,n_ ! dimensions of the input array + ! read the input + INTEGER :: lun = 90 ! File duplicated from STDIN + NAMELIST /DLRA/ nsv_filter + READ(lun,dlra) + m = m_ + n = n_ + info = 1 + ! Allocate the matrices + ALLOCATE(A_buff(m,n),Bf(m,n),Br(m,n)) + ALLOCATE(U(m,m),Sf(MIN(m,n)),Sr(MIN(m,n)),VT(n,n)) + ! Set the leading dimensions for the input and output arrays + lda = MAX(1, m) + ldu = MAX(1, m) + ldvt = MAX(1, n) + ALLOCATE(work(5*n), rwork(5*MIN(m,n))) + ! Compute the optimal workspace size + lwork = -1 +#ifdef SINGLE_PRECISION + CALL CGESVD('A', 'A', m, n, A_buff, lda, Sf, U, ldu, VT, ldvt, work, lwork, rwork, info) +#else + CALL ZGESVD('A', 'A', m, n, A_buff, lda, Sf, U, ldu, VT, ldvt, work, lwork, rwork, info) #endif - END SUBROUTINE test_svd - - ! SUBROUTINE test_svd - ! ! Program to perform Singular Value Decomposition (SVD) - ! ! using LAPACK library - - ! ! Specify the dimensions of the input matrix A - ! INTEGER, PARAMETER :: m = 3, n = 2 - ! INTEGER, PARAMETER :: lda = m - - ! ! Declare the input matrix A - ! REAL, DIMENSION(lda,n) :: A - - ! ! Specify the dimensions of the output matrices - ! INTEGER, PARAMETER :: ldu = m, ldvt = n - ! INTEGER, PARAMETER :: lwork = 5*n - ! REAL, DIMENSION(ldu,m) :: U - ! REAL, DIMENSION(n) :: S - ! REAL, DIMENSION(ldvt,n) :: VT - ! REAL, DIMENSION(lwork) :: work - ! INTEGER :: info,i,j - - ! ! Define the input matrix A - ! A = RESHAPE((/ 1.0, 2.0, 3.0, 4.0, 5.0, 6.0 /), SHAPE(A)) - - ! ! Compute the SVD of A using the LAPACK subroutine SGESVD - ! CALL SGESVD('A', 'A', m, n, A, lda, S, U, ldu, VT, ldvt, work, lwork, info) - - ! ! Print the results - ! WRITE(*,*) 'U = ' - ! DO i = 1, m - ! WRITE(*,'(6F8.3)') (U(i,j), j=1,m) - ! END DO - ! WRITE(*,*) - ! WRITE(*,*) 'S = ' - ! WRITE(*,'(2F8.3)') (S(i), i=1,n) - ! WRITE(*,*) - ! WRITE(*,*) 'VT = ' - ! DO i = 1, n - ! WRITE(*,'(6F8.3)') (VT(i,j), j=1,n) - ! END DO - - ! ! Reconstruct A from its SVD - ! A = MATMUL(U, MATMUL(diagmat(S,m,n), TRANSPOSE(VT))) - - ! ! Print the reconstructed matrix A - ! WRITE(*,*) 'Reconstructed matrix A = ' - ! DO i = 1, m - ! WRITE(*,'(2X, 3F8.3)') (A(i,j), j=1,n) - ! END DO - ! stop - ! END SUBROUTINE test_svd - - ! SUBROUTINE test_svd - ! IMPLICIT NONE - ! INTEGER, PARAMETER :: m = 3, n = 2 - ! COMPLEX(xp), DIMENSION(m, n) :: A - ! COMPLEX(xp), DIMENSION(m, m) :: U - ! COMPLEX(xp), DIMENSION(n, n) :: VT - ! REAL(xp), DIMENSION(MIN(m,n)) :: S - ! INTEGER :: i, j - - ! ! Initialize A - ! A = RESHAPE((/ (1.0_xp, 2.0_xp), (3.0_xp, 4.0_xp), (5.0_xp, 6.0_xp),& - ! (1.5_xp, 2.5_xp), (3.5_xp, 4.5_xp), (5.5_xp, 6.5_xp) /), [m, n]) - - ! ! Print input - ! WRITE(*,*) "A = " - ! DO i = 1, m - ! WRITE(*,"(3F8.3)") (REAL(A(i,j)), AIMAG(A(i,j)), j=1,n) - ! END DO - ! WRITE(*,*) - - ! ! Call the SVD subroutine - ! CALL svd(A, U, S, VT, m, n) - - ! ! Print the resultas - ! WRITE(*,*) "U = " - ! DO i = 1, m - ! WRITE(*,"(3F8.3)") (REAL(U(i,j)), AIMAG(U(i,j)), j=1,m) - ! END DO - ! WRITE(*,*) - - ! WRITE(*,*) "S = ", S - ! WRITE(*,*) - - ! WRITE(*,*) "VT = " - ! DO i = 1, n - ! WRITE(*,"(3F8.3)") (REAL(VT(i,j)), AIMAG(VT(i,j)), j=1,n) - ! END DO - ! END SUBROUTINE test_svd - - - SUBROUTINE svd(A, U, S, VT, m, n) + ! Allocate memory for the workspace arrays + lwork = 2*CEILING(REAL(work(1))) + DEALLOCATE(work) + ALLOCATE(work(lwork)) + END SUBROUTINE init_DLRA + + SUBROUTINE filter_sv_moments_ky_pj + USE fields, ONLY: moments + USE grid, ONLY: total_nky, total_np, total_nj, ngp,ngj,ngz,& + local_np, local_nj, local_nz, local_nkx, local_nky, local_na + USE time_integration, ONLY: updatetlevel + USE basic, ONLY: start_chrono, stop_chrono, chrono_DLRA IMPLICIT NONE - ! INPUT - COMPLEX(xp), DIMENSION(m,n), INTENT(IN) :: A - INTEGER, INTENT(IN) :: m, n - ! OUTPUT - COMPLEX(xp), DIMENSION(m,m), INTENT(OUT) :: U - REAL(xp), DIMENSION(MIN(m,n)), INTENT(OUT) :: S - COMPLEX(xp), DIMENSION(n,n), INTENT(OUT) :: VT - ! local variables - INTEGER :: lda, ldu, ldvt, info, lwork - COMPLEX(xp), DIMENSION(:), ALLOCATABLE :: work - REAL(xp), DIMENSION(:), ALLOCATABLE :: rwork -#ifdef LAPACKDIR - ! Set the leading dimensions for the input and output arrays - lda = MAX(1, m) - ldu = MAX(1, m) - ldvt = MAX(1, n) - - ! Compute the optimal workspace size - lwork = -1 - CALL ZGESVD('A', 'A', m, n, A, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) - - ! Allocate memory for the workspace arrays - lwork = CEILING(REAL(work(1)), KIND=SELECTED_REAL_KIND(1, 6)) - ALLOCATE(work(lwork), rwork(5*MIN(m,n))) - - ! Compute the SVD - CALL ZGESVD('A', 'A', m, n, A, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) - - ! Free the workspace arrays - DEALLOCATE(work, rwork) + + ! Arguments + INTEGER :: nsv_filter ! number of singular values to keep + ! Local variables + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: moments_lky_lpj ! local ky and local pj data + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: moments_gky_lpj ! global ky, local pj data + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: moments_gky_gpj ! full gathered data for SVD (input of SVD) + INTEGER :: ia,ix,iz, m,n, ip, ij, iy + CALL start_chrono(chrono_DLRA) + ALLOCATE(moments_lky_lpj(local_nky,local_np*local_nj)) + ALLOCATE(moments_gky_lpj(total_nky,local_np*local_nj)) + ALLOCATE(moments_gky_gpj(total_nky,total_np*total_nj)) + DO iz = 1+ngz/2,local_nz+ngz/2 + DO ix = 1,local_nkx + DO ia = 1,local_na + ! Build the local slice explicitely + DO ip = 1,local_np + DO ij = 1,local_nj + DO iy = 1,local_nky + moments_lky_lpj(iy,local_np*(ij-1)+ip) = moments(ia,ip+ngp/2,ij+ngj/2,iy,ix,iz,updatetlevel) + ENDDO + ENDDO + ENDDO + ! Gather ky data + IF(num_procs_ky .GT. 1) THEN + ! MPI communication + ELSE + moments_gky_lpj = moments_lky_lpj + ENDIF + ! Gather p data + IF(num_procs_p .GT. 1) THEN + ! MPI communication + ELSE + moments_gky_gpj = moments_gky_lpj + ENDIF + ! The process 0 performs the SVD + IF(my_id .EQ. 0) THEN + m = total_nky + n = total_np*total_nj + nsv_filter = -1 + CALL filter_singular_value(moments_gky_gpj) + ENDIF + ! Distribute ky data + IF(num_procs_ky .GT. 1) THEN + ! MPI communication + ELSE + moments_gky_lpj = moments_gky_gpj + ENDIF + ! Distribute p data + IF(num_procs_p .GT. 1) THEN + ! MPI communication + ELSE + moments_lky_lpj = moments_gky_lpj + ENDIF + ! Put back the data into the moments array + DO ip = 1,local_np + DO ij = 1,local_nj + DO iy = 1,local_nky + moments(ia,ip+ngp/2,ij+ngj/2,iy,ix,iz,updatetlevel) = moments_lky_lpj(iy,local_np*(ij-1)+ip) + ENDDO + ENDDO + ENDDO + + ENDDO + ENDDO + ENDDO + CALL stop_chrono(chrono_DLRA) + END SUBROUTINE filter_sv_moments_ky_pj + + SUBROUTINE filter_singular_value(A) + IMPLICIT NONE + ! ARGUMENTS + COMPLEX(xp), DIMENSION(:,:), INTENT(INOUT) :: A ! Array to filter + ! copy of the input since it is changed in the svd procedure + A_buff = A; +#ifdef SINGLE_PRECISION + CALL CGESVD('A', 'A', m, n, A_buff, lda, Sf, U, ldu, VT, ldvt, work, lwork, rwork, info) +#else + CALL ZGESVD('A', 'A', m, n, A_buff, lda, Sf, U, ldu, VT, ldvt, work, lwork, rwork, info) #endif - END SUBROUTINE svd - - - FUNCTION diagmat(S, m, n) RESULT(D) + IF(info.GT.0) print*,"SVD did not converge, info=",info + ! Filter the values + Sr = 0._xp + IF (nsv_filter .GT. 0) THEN + DO i=1,MIN(m,n)-nsv_filter + Sr(i) = Sf(i) + ENDDO + ELSE ! do not filter if nsv_filter<0 + Sr = Sf + ENDIF + ! Reconstruct A from its reduced SVD + A = MATMUL(U, MATMUL(diagmat(Sr,m,n), VT)) ! reduced + END SUBROUTINE filter_singular_value + + FUNCTION diagmat(S, m, n) RESULT(D) IMPLICIT NONE ! INPUT - REAL, DIMENSION(:), INTENT(IN) :: S + REAL(xp), DIMENSION(:), INTENT(IN) :: S INTEGER, INTENT(IN) :: m, n ! OUTPUT - COMPLEX, DIMENSION(m,n) :: D + COMPLEX(xp), DIMENSION(m,n) :: D ! Local variables - INTEGER :: i, j - + INTEGER :: i ! Initialize the output array to zero D = 0.0 - ! Fill the diagonal elements of the output array with the input vector S DO i = 1, MIN(m,n) - D(i,i) = S(i) + D(i,i) = S(i) END DO - - END FUNCTION diagmat + END FUNCTION diagmat -end module DLRA \ No newline at end of file + SUBROUTINE test_svd + ! Specify the dimensions of the input matrix A + INTEGER :: m,n + + ! Declare the input matrix A and reconstructed matrix B + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: A,B,A_buff + + ! OUTPUT + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: U + REAL(xp), DIMENSION(:), ALLOCATABLE :: S + COMPLEX(xp), DIMENSION(:,:), ALLOCATABLE :: VT + ! local variables + INTEGER :: lda, ldu, ldvt, info, lwork, i, j + COMPLEX(xp), DIMENSION(:), ALLOCATABLE :: work + REAL(xp), DIMENSION(:), ALLOCATABLE :: rwork + + m = 3 + n = 2 + ALLOCATE(A_buff(m,n),A(m,n),B(m,n),U(m,m),S(MIN(m,n)),VT(n,n)) + ! Set the leading dimensions for the input and output arrays + lda = MAX(1, m) + ldu = MAX(1, m) + ldvt = MAX(1, n) + + ! Define the input matrix A + A = RESHAPE((/ (1._xp,0.1_xp), (2._xp,0.2_xp), (3._xp,0.3_xp), (4._xp,0.4_xp), (5._xp,0.5_xp), (6._xp,0.6_xp) /), SHAPE(A)) + ! copy of the input since it is changed in the svd procedure + A_buff = A; + ! Print the input matrix A + WRITE(*,*) 'Input matrix A = ' + DO i = 1, m + WRITE(*,*) ('(',REAL(A(i,j)), AIMAG(A(i,j)),')', j=1,n) + END DO + + ! CALL svd(A, U, S, VT, m, n) + ALLOCATE(work(5*n), rwork(5*n)) + ! Compute the optimal workspace size + lwork = -1 +#ifdef SINGLE_PRECISION + CALL CGESVD('A', 'A', m, n, A_buff, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) +#else + CALL ZGESVD('A', 'A', m, n, A_buff, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) +#endif + + ! Allocate memory for the workspace arrays + lwork = CEILING(REAL(work(1)), KIND=SELECTED_REAL_KIND(1, 6)) + + ! Compute the SVD of A using the LAPACK subroutine CGESVD +#ifdef SINGLE_PRECISION + CALL CGESVD('A', 'A', m, n, A_buff, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) +#else + CALL ZGESVD('A', 'A', m, n, A_buff, lda, S, U, ldu, VT, ldvt, work, lwork, rwork, info) +#endif + ! Print the results + ! WRITE(*,*) 'U = ' + ! DO i = 1, m + ! WRITE(*,*) ('(',REAL(U(i,j)), AIMAG(U(i,j)),')', j=1,m) + ! END DO + ! WRITE(*,*) + WRITE(*,*) 'S = ' + WRITE(*,'(2F8.3)') (S(i), i=1,n) + WRITE(*,*) + ! WRITE(*,*) 'VT = ' + ! DO i = 1, n + ! WRITE(*,*) ('(',REAL(VT(i,j)), AIMAG(VT(i,j)),')', j=1,n) + ! END DO + + ! Reconstruct A from its SVD + B = MATMUL(U, MATMUL(diagmat(S,m,n), VT)) + ! Print the error with the intput matrix + WRITE(*,*) '||A-USVT||=', sum(abs(A-B)) + stop + END SUBROUTINE test_svd +#endif +end module DLRA diff --git a/src/auxval.F90 b/src/auxval.F90 index fb8e13cae4b15f794ede5770f42dc2671cffbbdd..136e4bc0980540b783a4d6b78691374e51cb394c 100644 --- a/src/auxval.F90 +++ b/src/auxval.F90 @@ -12,6 +12,9 @@ subroutine auxval USE closure, ONLY: set_closure_model, hierarchy_closure USE parallel, ONLY: init_parallel_var, my_id, num_procs, num_procs_p, num_procs_z, num_procs_ky, rank_p, rank_ky, rank_z USE processing, ONLY: init_process +#ifdef TEST_SVD + USE DLRA, ONLY: init_DLRA +#endif IMPLICIT NONE INTEGER :: i_, ierr @@ -42,6 +45,10 @@ subroutine auxval CALL set_closure_model ! set the closure scheme in use +#ifdef TEST_SVD + CALL init_DLRA(local_nky,local_np*local_nj) +#endif + !! Display parallel settings CALL mpi_barrier(MPI_COMM_WORLD, ierr) DO i_ = 0,num_procs-1 diff --git a/src/basic_mod.F90 b/src/basic_mod.F90 index 0784de192446f954d2d62854826dae745c35ecb6..2aa6dfd8f5b26cec7d3e1382068ff4b522bbc4d6 100644 --- a/src/basic_mod.F90 +++ b/src/basic_mod.F90 @@ -40,6 +40,10 @@ MODULE basic type(chrono), PUBLIC, PROTECTED :: chrono_runt, chrono_mrhs, chrono_advf, chrono_pois, chrono_sapj,& chrono_diag, chrono_chck, chrono_step, chrono_clos, chrono_ghst, chrono_coll, chrono_napj, chrono_grad +#ifdef TEST_SVD + type(chrono), PUBLIC, PROTECTED :: chrono_DLRA +#endif + LOGICAL, PUBLIC, PROTECTED :: GATHERV_OUTPUT = .true. PUBLIC :: allocate_array, basic_outputinputs,basic_data,& @@ -85,6 +89,9 @@ CONTAINS chrono_chck%ttot = 0 chrono_diag%ttot = 0 chrono_step%ttot = 0 +#ifdef TEST_SVD + chrono_DLRA%ttot = 0 +#endif END SUBROUTINE basic_data diff --git a/src/diagnose.F90 b/src/diagnose.F90 index c3be68638cef60832c2f3790c9d5c0e162fb791c..e9f89c5848d918355e9e71597d2e6ddeccc6e807 100644 --- a/src/diagnose.F90 +++ b/src/diagnose.F90 @@ -127,6 +127,9 @@ SUBROUTINE diagnose_full(kstep) CALL creatd(fidres, 0, dims, "/profiler/Tc_diag", "cumulative sym computation time") CALL creatd(fidres, 0, dims, "/profiler/Tc_step", "cumulative total step computation time") CALL creatd(fidres, 0, dims, "/profiler/time", "current simulation time") +#ifdef TEST_SVD + CALL creatd(fidres, 0, (/0/), "/profiler/Tc_DLRA", "cumulative total DLRA computation time") +#endif ! Grid info CALL creatg(fidres, "/data/grid", "Grid data") CALL putarr(fidres, "/data/grid/coordkx", kxarray_full, "kx*rho_s0", ionode=0) @@ -169,6 +172,15 @@ SUBROUTINE diagnose_full(kstep) ENDIF CALL attach(fidres,"/data/var0d/" , "frames", iframe0d) END IF + ! var2d group (gyro transport) + IF (nsave_0d .GT. 0) THEN + CALL creatg(fidres, "/data/var2d", "2d profiles") + CALL creatd(fidres, rank, dims, "/data/var2d/time", "Time t*c_s/R") + CALL creatd(fidres, rank, dims, "/data/var2d/cstep", "iteration number") +#ifdef TEST_SVD + CALL creatg(fidres, "/data/var2d/sv_ky_pj", "singular values of the moment ky/pj cut") +#endif + ENDIF ! var3d group (phi,psi, fluid moments, Ni00, Napjz) IF (nsave_3d .GT. 0) THEN CALL creatg(fidres, "/data/var3d", "3d profiles") @@ -221,6 +233,12 @@ SUBROUTINE diagnose_full(kstep) CALL diagnose_0d END IF END IF + ! 2.2 2d profiles + IF (nsave_2d .GT. 0) THEN + IF (MOD(cstep, nsave_2d) == 0) THEN + CALL diagnose_2d + ENDIF + ENDIF ! 2.3 3d profiles IF (nsave_3d .GT. 0) THEN IF (MOD(cstep, nsave_3d) == 0) THEN @@ -274,7 +292,6 @@ SUBROUTINE diagnose_0d CALL append(fidres, "/profiler/Tc_nadiab", REAL(chrono_napj%ttot,dp),ionode=0) CALL append(fidres, "/profiler/Tc_step", REAL(chrono_step%ttot,dp),ionode=0) #ifdef TEST_SVD - CALL creatd(fidres, 0, (/0/), "/profiler/Tc_DLRA", "cumulative total DLRA computation time") CALL append(fidres, "/profiler/Tc_DLRA", REAL(chrono_DLRA%ttot,dp),ionode=0) #endif CALL append(fidres, "/profiler/time", REAL(time,dp),ionode=0) @@ -296,6 +313,25 @@ SUBROUTINE diagnose_0d ENDIF END SUBROUTINE diagnose_0d +SUBROUTINE diagnose_2d + USE prec_const + USE basic + USE diagnostics_par + USE futils, ONLY: putarr, append +#ifdef TEST_SVD + USE DLRA, ONLY: Sf +#endif + IMPLICIT NONE + CHARACTER(50) :: dset_name + iframe2d=iframe2d+1 + CALL append(fidres,"/data/var2d/time", REAL(time,dp), ionode=0) + CALL append(fidres,"/data/var2d/cstep",REAL(cstep,dp),ionode=0) +#ifdef TEST_SVD + WRITE(dset_name, "(A, '/', i6.6)") "/data/var2d/sv_ky_pj/", iframe2d + CALL putarr(fidres, dset_name, Sf, ionode=0) +#endif +END SUBROUTINE + SUBROUTINE diagnose_3d USE basic USE futils, ONLY: append, getatt, attach, putarrnd, putarr diff --git a/src/stepon.F90 b/src/stepon.F90 index 71ad932a0bec6ed56a393040909c74fe3dab66cf..930a6b2c594127317f1af0636388c1d35c69e593 100644 --- a/src/stepon.F90 +++ b/src/stepon.F90 @@ -8,7 +8,9 @@ SUBROUTINE stepon use mpi, ONLY: MPI_COMM_WORLD USE time_integration, ONLY: ntimelevel USE prec_const, ONLY: xp - USE DLRA, ONLY: test_svd +#ifdef TEST_SVD + USE DLRA, ONLY: test_svd,filter_sv_moments_ky_pj +#endif IMPLICIT NONE INTEGER :: num_step, ierr @@ -56,9 +58,9 @@ SUBROUTINE stepon CALL stop_chrono(chrono_chck) !! TEST SINGULAR VALUE DECOMPOSITION - ! CALL filter_singular_value_ky_pj(nsv,moments) #ifdef TEST_SVD - CALL test_svd + ! CALL test_svd + CALL filter_sv_moments_ky_pj #endif IF( nlend ) EXIT ! exit do loop diff --git a/testcases/DLRA_zpinch/base_case/fort_00.90 b/testcases/DLRA_zpinch/base_case/fort_00.90 new file mode 100644 index 0000000000000000000000000000000000000000..6caf3d7364d7fff512d4ef89094856110f81da3b --- /dev/null +++ b/testcases/DLRA_zpinch/base_case/fort_00.90 @@ -0,0 +1,107 @@ +&BASIC + nrun = 99999999 + dt = 0.01 + tmax = 500 + maxruntime = 72000 + job2load = -1 +/ +&GRID + pmax = 4 + jmax = 2 + Nx = 64 + Lx = 200 + Ny = 48 + Ly = 60 + Nz = 1 + SG = .f. + Nexc = 1 +/ +&GEOMETRY + geom = 'Z-pinch' + q0 = 0.0 + shear = 0.0 + eps = 0.0 + kappa = 1.0 + s_kappa= 0.0 + delta = 0.0 + s_delta= 0.0 + zeta = 0.0 + s_zeta = 0.0 + parallel_bc = 'shearless' + shift_y= 0.0 +/ +&OUTPUT_PAR + dtsave_0d = 0.1 + dtsave_1d = -1 + dtsave_2d = 0.1 + dtsave_3d = 1 + dtsave_5d = 10 + write_doubleprecision = .f. + write_gamma = .t. + write_hf = .t. + write_phi = .t. + write_Na00 = .t. + write_Napj = .t. + write_dens = .t. + write_fvel = .t. + write_temp = .t. +/ +&MODEL_PAR + LINEARITY = 'nonlinear' + Na = 2 ! number of species + mu_x = 1.0 + mu_y = 1.0 + N_HD = 4 + mu_z = 0.0 + HYP_V = 'hypcoll' + mu_p = 0.0 + mu_j = 0.0 + nu = 0.1 + beta = 0.0 + ADIAB_E = .f. + tau_e = 1.0 +/ +&CLOSURE_PAR + hierarchy_closure='truncation' + !hierarchy_closure='max_degree' + dmax = 2 + nonlinear_closure='anti_laguerre_aliasing' !(truncation,full_sum,anti_laguerre_aliasing) + nmax = 0 +/ +&SPECIES + ! ions + name_ = 'ions' + tau_ = 1.0 + sigma_= 1.0 + q_ = 1.0 + k_N_ = 2.0 + k_T_ = 0.4 +/ +&SPECIES + ! electrons + name_ = 'electrons' + tau_ = 1.0 + sigma_= 0.023338 + q_ =-1.0 + k_N_ = 2.0 + k_T_ = 0.4 +/ +&COLLISION_PAR + collision_model = 'DG' !DG/SG/PA/LD (dougherty, sugama, pitch angle, landau) + GK_CO = .t. + INTERSPECIES = .true. + mat_file = 'gk_sugama_P_20_J_10_N_150_kpm_8.0.h5' +/ +&INITIAL_CON + INIT_OPT = 'blob' !(phi,blob) + ACT_ON_MODES = 'donothing' + init_background = 0.0 + init_noiselvl = 0.005 + iseed = 42 +/ +&TIME_INTEGRATION_PAR + numerical_scheme = 'RK4' +/ +&DLRA + nsv_filter = 0 +/ diff --git a/testcases/DLRA_zpinch/base_case/gyacomo23_sp b/testcases/DLRA_zpinch/base_case/gyacomo23_sp new file mode 120000 index 0000000000000000000000000000000000000000..db5b14c74c564cba8f17dc48eca9ccefea4590da --- /dev/null +++ b/testcases/DLRA_zpinch/base_case/gyacomo23_sp @@ -0,0 +1 @@ +../../../bin/gyacomo23_sp \ No newline at end of file diff --git a/testcases/DLRA_zpinch/base_case/gyacomo23_test_svd b/testcases/DLRA_zpinch/base_case/gyacomo23_test_svd new file mode 120000 index 0000000000000000000000000000000000000000..d0950bb224c5d1524f6e027b0af405fb4d816e65 --- /dev/null +++ b/testcases/DLRA_zpinch/base_case/gyacomo23_test_svd @@ -0,0 +1 @@ +../../../bin/gyacomo23_test_svd \ No newline at end of file diff --git a/testcases/DLRA_zpinch/nsv_filter_2/fort_00.90 b/testcases/DLRA_zpinch/nsv_filter_2/fort_00.90 new file mode 100644 index 0000000000000000000000000000000000000000..1235695ede65b5603c8af2c83b2cbc382398e28c --- /dev/null +++ b/testcases/DLRA_zpinch/nsv_filter_2/fort_00.90 @@ -0,0 +1,107 @@ +&BASIC + nrun = 99999999 + dt = 0.01 + tmax = 500 + maxruntime = 72000 + job2load = -1 +/ +&GRID + pmax = 4 + jmax = 2 + Nx = 64 + Lx = 200 + Ny = 48 + Ly = 60 + Nz = 1 + SG = .f. + Nexc = 1 +/ +&GEOMETRY + geom = 'Z-pinch' + q0 = 0.0 + shear = 0.0 + eps = 0.0 + kappa = 1.0 + s_kappa= 0.0 + delta = 0.0 + s_delta= 0.0 + zeta = 0.0 + s_zeta = 0.0 + parallel_bc = 'shearless' + shift_y= 0.0 +/ +&OUTPUT_PAR + dtsave_0d = 0.1 + dtsave_1d = -1 + dtsave_2d = 0.1 + dtsave_3d = 1 + dtsave_5d = 10 + write_doubleprecision = .f. + write_gamma = .t. + write_hf = .t. + write_phi = .t. + write_Na00 = .t. + write_Napj = .t. + write_dens = .t. + write_fvel = .t. + write_temp = .t. +/ +&MODEL_PAR + LINEARITY = 'nonlinear' + Na = 2 ! number of species + mu_x = 1.0 + mu_y = 1.0 + N_HD = 4 + mu_z = 0.0 + HYP_V = 'hypcoll' + mu_p = 0.0 + mu_j = 0.0 + nu = 0.1 + beta = 0.0 + ADIAB_E = .f. + tau_e = 1.0 +/ +&CLOSURE_PAR + hierarchy_closure='truncation' + !hierarchy_closure='max_degree' + dmax = 2 + nonlinear_closure='anti_laguerre_aliasing' !(truncation,full_sum,anti_laguerre_aliasing) + nmax = 0 +/ +&SPECIES + ! ions + name_ = 'ions' + tau_ = 1.0 + sigma_= 1.0 + q_ = 1.0 + k_N_ = 2.0 + k_T_ = 0.4 +/ +&SPECIES + ! electrons + name_ = 'electrons' + tau_ = 1.0 + sigma_= 0.023338 + q_ =-1.0 + k_N_ = 2.0 + k_T_ = 0.4 +/ +&COLLISION_PAR + collision_model = 'DG' !DG/SG/PA/LD (dougherty, sugama, pitch angle, landau) + GK_CO = .t. + INTERSPECIES = .true. + mat_file = 'gk_sugama_P_20_J_10_N_150_kpm_8.0.h5' +/ +&INITIAL_CON + INIT_OPT = 'blob' !(phi,blob) + ACT_ON_MODES = 'donothing' + init_background = 0.0 + init_noiselvl = 0.005 + iseed = 42 +/ +&TIME_INTEGRATION_PAR + numerical_scheme = 'RK4' +/ +&DLRA + nsv_filter = 2 +/ diff --git a/testcases/DLRA_zpinch/nsv_filter_2/gyacomo23_test_svd b/testcases/DLRA_zpinch/nsv_filter_2/gyacomo23_test_svd new file mode 120000 index 0000000000000000000000000000000000000000..d0950bb224c5d1524f6e027b0af405fb4d816e65 --- /dev/null +++ b/testcases/DLRA_zpinch/nsv_filter_2/gyacomo23_test_svd @@ -0,0 +1 @@ +../../../bin/gyacomo23_test_svd \ No newline at end of file diff --git a/testcases/DLRA_zpinch/nsv_filter_6/fort_00.90 b/testcases/DLRA_zpinch/nsv_filter_6/fort_00.90 new file mode 100644 index 0000000000000000000000000000000000000000..a23d82d4fea4e31b71500a4565d7e429a836ca15 --- /dev/null +++ b/testcases/DLRA_zpinch/nsv_filter_6/fort_00.90 @@ -0,0 +1,107 @@ +&BASIC + nrun = 99999999 + dt = 0.01 + tmax = 500 + maxruntime = 72000 + job2load = -1 +/ +&GRID + pmax = 4 + jmax = 2 + Nx = 64 + Lx = 200 + Ny = 48 + Ly = 60 + Nz = 1 + SG = .f. + Nexc = 1 +/ +&GEOMETRY + geom = 'Z-pinch' + q0 = 0.0 + shear = 0.0 + eps = 0.0 + kappa = 1.0 + s_kappa= 0.0 + delta = 0.0 + s_delta= 0.0 + zeta = 0.0 + s_zeta = 0.0 + parallel_bc = 'shearless' + shift_y= 0.0 +/ +&OUTPUT_PAR + dtsave_0d = 0.1 + dtsave_1d = -1 + dtsave_2d = 0.1 + dtsave_3d = 1 + dtsave_5d = 10 + write_doubleprecision = .f. + write_gamma = .t. + write_hf = .t. + write_phi = .t. + write_Na00 = .t. + write_Napj = .t. + write_dens = .t. + write_fvel = .t. + write_temp = .t. +/ +&MODEL_PAR + LINEARITY = 'nonlinear' + Na = 2 ! number of species + mu_x = 1.0 + mu_y = 1.0 + N_HD = 4 + mu_z = 0.0 + HYP_V = 'hypcoll' + mu_p = 0.0 + mu_j = 0.0 + nu = 0.1 + beta = 0.0 + ADIAB_E = .f. + tau_e = 1.0 +/ +&CLOSURE_PAR + hierarchy_closure='truncation' + !hierarchy_closure='max_degree' + dmax = 2 + nonlinear_closure='anti_laguerre_aliasing' !(truncation,full_sum,anti_laguerre_aliasing) + nmax = 0 +/ +&SPECIES + ! ions + name_ = 'ions' + tau_ = 1.0 + sigma_= 1.0 + q_ = 1.0 + k_N_ = 2.0 + k_T_ = 0.4 +/ +&SPECIES + ! electrons + name_ = 'electrons' + tau_ = 1.0 + sigma_= 0.023338 + q_ =-1.0 + k_N_ = 2.0 + k_T_ = 0.4 +/ +&COLLISION_PAR + collision_model = 'DG' !DG/SG/PA/LD (dougherty, sugama, pitch angle, landau) + GK_CO = .t. + INTERSPECIES = .true. + mat_file = 'gk_sugama_P_20_J_10_N_150_kpm_8.0.h5' +/ +&INITIAL_CON + INIT_OPT = 'blob' !(phi,blob) + ACT_ON_MODES = 'donothing' + init_background = 0.0 + init_noiselvl = 0.005 + iseed = 42 +/ +&TIME_INTEGRATION_PAR + numerical_scheme = 'RK4' +/ +&DLRA + nsv_filter = 6 +/ diff --git a/testcases/DLRA_zpinch/nsv_filter_6/gyacomo23_test_svd b/testcases/DLRA_zpinch/nsv_filter_6/gyacomo23_test_svd new file mode 120000 index 0000000000000000000000000000000000000000..d0950bb224c5d1524f6e027b0af405fb4d816e65 --- /dev/null +++ b/testcases/DLRA_zpinch/nsv_filter_6/gyacomo23_test_svd @@ -0,0 +1 @@ +../../../bin/gyacomo23_test_svd \ No newline at end of file