!---------------------------------------------------------------------- ! NEMO system team, System and Interface for oceanic RElocable Nesting !---------------------------------------------------------------------- ! ! MODULE: multi ! ! ! DESCRIPTION: !> This module manage multi file structure ! !> @details !> define type TMULTI:
!> TYPE(TMULTI) :: tl_multi
!> !> @author !> J.Paul ! REVISION HISTORY: !> @date 2013 - Initial Version ! !> @note Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) !---------------------------------------------------------------------- MODULE multi USE kind ! F90 kind parameter USE logger ! log file manager USE fct ! basic useful function USE dim ! dimension manager USE att ! attribute manager USE var ! variable manager USE file ! file manager IMPLICIT NONE PRIVATE ! NOTE_avoid_public_variables_if_possible ! type and variable PUBLIC :: TMULTI ! multi file structure ! function and subroutine PUBLIC :: ASSIGNMENT(=) !< copy multi structure PUBLIC :: multi_init !< initialise mpp structure PUBLIC :: multi_clean !< clean mpp strcuture PUBLIC :: multi_print !< print information about mpp structure PUBLIC :: multi_add_file !< add one proc strucutre in mpp structure ! PUBLIC :: multi_del_file !< delete one proc strucutre in mpp structure ! PUBLIC :: multi_move_file !< overwrite proc strucutre in mpp structure !> @struct TMULTI TYPE TMULTI ! general INTEGER(i4) :: i_nfile = 0 !< number of files INTEGER(i4) :: i_nvar = 0 !< total number of variables TYPE(TFILE), DIMENSION(:), POINTER :: t_file => NULL() !< files composing multi END TYPE INTERFACE ASSIGNMENT(=) MODULE PROCEDURE multi__copy ! copy multi file structure END INTERFACE CONTAINS !------------------------------------------------------------------- !> @brief !> This function copy multi file structure in another multi file !> structure !> @details !> file variable value are copied in a temporary table, !> so input and output file structure value do not point on the same !> "memory cell", and so on are independant. !> !> @warning to avoid infinite loop, do not use any function inside !> this subroutine !> !> @author J.Paul !> - Nov, 2013- Initial Version ! !> @param[out] td_multi1 : file structure !> @param[in] td_multi2 : file structure !------------------------------------------------------------------- !> @code SUBROUTINE multi__copy( td_multi1, td_multi2 ) IMPLICIT NONE ! Argument TYPE(TMULTI), INTENT(OUT) :: td_multi1 TYPE(TMULTI), INTENT(IN) :: td_multi2 ! loop indices INTEGER(i4) :: ji !---------------------------------------------------------------- CALL logger_trace("COPY: mulit file ") td_multi1%i_nfile = td_multi2%i_nfile td_multi1%i_nvar = td_multi2%i_nvar ! copy variable structure IF( ASSOCIATED(td_multi1%t_file) ) DEALLOCATE(td_multi1%t_file) IF( ASSOCIATED(td_multi2%t_file) .AND. td_multi1%i_nfile > 0 )THEN ALLOCATE( td_multi1%t_file(td_multi1%i_nfile) ) DO ji=1,td_multi1%i_nfile td_multi1%t_file(ji) = td_multi2%t_file(ji) ENDDO ENDIF END SUBROUTINE multi__copy !> @endcode !------------------------------------------------------------------- !> @brief This subroutine initialize multi file structure. ! !> @author J.Paul !> - Nov, 2013- Initial Version ! !> @param[in] cd_varfile : variable location information (from namelist) !> @return td_multi : multi structure !------------------------------------------------------------------- ! @code FUNCTION multi_init(cd_varfile) IMPLICIT NONE ! Argument CHARACTER(LEN=*), DIMENSION(:), INTENT(IN) :: cd_varfile ! function TYPE(TMULTI) :: multi_init ! local variable CHARACTER(LEN=lc) :: cl_name CHARACTER(LEN=lc) :: cl_file CHARACTER(LEN=lc) :: cl_matrix INTEGER(i4) :: il_fileid TYPE(TVAR) :: tl_var TYPE(TFILE) :: tl_file TYPE(TMULTI) :: tl_multi ! loop indices INTEGER(i4) :: ji !---------------------------------------------------------------- ji=1 DO WHILE( TRIM(cd_varfile(ji)) /= '' ) cl_name=fct_lower(fct_split(cd_varfile(ji),1,':')) cl_file=fct_split(cd_varfile(ji),2,':') IF( TRIM(cl_name) /= '' )THEN IF( TRIM(cl_file) /= '' )THEN cl_matrix='' IF( fct_is_num(cl_file(1:1)) )THEN cl_matrix=TRIM(cl_file) WRITE(cl_file,'(a,i2.2)')'data_',ji ENDIF ! get file id tl_file=file_init(TRIM(cl_file)) il_fileid=multi_add_file(tl_multi,tl_file) ! define variable tl_var=var_init(TRIM(cl_name)) CALL var_read_matrix(tl_var, cl_matrix) ! add variable CALL file_add_var(tl_multi%t_file(il_fileid),tl_var) ! update total number of variable tl_multi%i_nvar=tl_multi%i_nvar+1 ! clean structure CALL var_clean(tl_var) ELSE CALL logger_error("MULTI INIT: file name matching variable "//& & TRIM(cl_name)//" is empty. check namelist.") ENDIF ELSE CALL logger_error("MULTI INIT: variable name "//& & "is empty. check namelist.") ENDIF ji=ji+1 ENDDO ! save result multi_init=tl_multi END FUNCTION multi_init ! @endcode !------------------------------------------------------------------- !> @brief This subroutine clean multi file strucutre. ! !> @author J.Paul !> - Nov, 2013- Initial Version ! !> @param[in] td_multi : multi file structure !------------------------------------------------------------------- ! @code SUBROUTINE multi_clean(td_multi) IMPLICIT NONE ! Argument TYPE(TMULTI), INTENT(INOUT) :: td_multi ! local variable TYPE(TMULTI) :: tl_multi ! empty multi file structure ! loop indices INTEGER(i4) :: ji !---------------------------------------------------------------- CALL logger_info( " CLEAN: reset multi file " ) IF( ASSOCIATED( td_multi%t_file ) )THEN DO ji=td_multi%i_nfile,1,-1 CALL file_clean(td_multi%t_file(ji)) ENDDO DEALLOCATE(td_multi%t_file) ENDIF ! replace by empty structure td_multi=tl_multi END SUBROUTINE multi_clean ! @endcode !------------------------------------------------------------------- !> @brief This subroutine print some information about mpp strucutre. ! !> @author J.Paul !> - Nov, 2013- Initial Version ! !> @param[in] td_mpp : mpp structure !------------------------------------------------------------------- ! @code SUBROUTINE multi_print(td_multi) IMPLICIT NONE ! Argument TYPE(TMULTI), INTENT(IN) :: td_multi ! local variable ! loop indices INTEGER(i4) :: ji INTEGER(i4) :: jj !---------------------------------------------------------------- ! print file IF( td_multi%i_nfile /= 0 .AND. ASSOCIATED(td_multi%t_file) )THEN WRITE(*,'(/a,i3)') 'MULTI: total number of file: ',& & td_multi%i_nfile WRITE(*,'(6x,a,i3)') ' total number of variable: ',& & td_multi%i_nvar DO ji=1,td_multi%i_nfile WRITE(*,'(3x,3a)') 'FILE ',TRIM(td_multi%t_file(ji)%c_name),& & ' CONTAINS' DO jj=1,td_multi%t_file(ji)%i_nvar IF( ASSOCIATED(td_multi%t_file(ji)%t_var) )THEN WRITE(*,'(6x,a/)') TRIM(td_multi%t_file(ji)%t_var(jj)%c_name) ENDIF ENDDO ENDDO ENDIF END SUBROUTINE multi_print ! @endcode !------------------------------------------------------------------- !> @brief !> This subroutine add file to multi file structure. !> !> @detail ! !> @author J.Paul !> - Nov, 2013- Initial Version ! !> @param[inout] td_multi : multi file strcuture !> @param[in] td_file : file strcuture !> @return file id in multi structure !------------------------------------------------------------------- !> @code FUNCTION multi_add_file( td_multi, td_file ) IMPLICIT NONE ! Argument TYPE(TMULTI), INTENT(INOUT) :: td_multi TYPE(TFILE) , INTENT(IN) :: td_file ! function INTEGER(i4) :: multi_add_file ! local variable INTEGER(i4) :: il_status INTEGER(i4) :: il_fileid TYPE(TFILE), DIMENSION(:), ALLOCATABLE :: tl_file !---------------------------------------------------------------- il_fileid=0 IF( ASSOCIATED(td_multi%t_file) )THEN il_fileid=file_get_id(td_multi%t_file(:),TRIM(td_file%c_name)) ENDIF IF( il_fileid /= 0 )THEN multi_add_file=il_fileid ELSE CALL logger_trace("MULTI ADD FILE: add file "//& & TRIM(td_file%c_name)//" in multi structure") IF( td_multi%i_nfile > 0 )THEN ! ! already other file in multi structure ALLOCATE( tl_file(td_multi%i_nfile), stat=il_status ) IF(il_status /= 0 )THEN CALL logger_error( " MULTI ADD FILE: not enough space to put file & & in multi structure") ELSE ! save temporary multi structure tl_file(:)=td_multi%t_file(:) DEALLOCATE( td_multi%t_file ) ALLOCATE( td_multi%t_file(td_multi%i_nfile+1), stat=il_status) IF(il_status /= 0 )THEN CALL logger_error( " MULTI ADD FILE: not enough space to put "//& & "file in multi structure ") ENDIF ! copy file in multi before td_multi%t_file(1:td_multi%i_nfile) = tl_file(:) DEALLOCATE(tl_file) ENDIF ELSE ! no processor in mpp structure IF( ASSOCIATED(td_multi%t_file) )THEN DEALLOCATE(td_multi%t_file) ENDIF ALLOCATE( td_multi%t_file(td_multi%i_nfile+1), stat=il_status ) IF(il_status /= 0 )THEN CALL logger_error( " MULTI ADD FILE: not enough space to put "//& & "file in multi structure " ) ENDIF ENDIF td_multi%i_nfile=td_multi%i_nfile+1 ! add new file td_multi%t_file(td_multi%i_nfile)=td_file multi_add_file=td_multi%i_nfile ENDIF END FUNCTION multi_add_file !> @endcode END MODULE multi