Skip to content
Snippets Groups Projects
obl_init.f90 6.21 KiB
Newer Older
  • Learn to ignore specific revisions
  •     !< @brief initial conditions module
    
        ! --------------------------------------------------------------------------------
    
        ! modules used
        ! --------------------------------------------------------------------------------
    
    #ifdef USE_CONFIG_PARSER
        use iso_c_binding, only: C_NULL_CHAR
        use config_parser
    #endif
    
        use obl_grid
        use obl_math
    
    
        ! --------------------------------------------------------------------------------
    
        implicit none
    
        private
    
        ! public interface
        ! --------------------------------------------------------------------------------
        public :: set_const_profile, set_linear_profile, set_external_profile
    
        public :: set_config_profile
    
        ! --------------------------------------------------------------------------------
    
    
        ! --------------------------------------------------------------------------------
        subroutine set_const_profile(F, Fsurf, grid)
            !< @brief set constant profile
            ! ----------------------------------------------------------------------------
            type (gridDataType), intent(in) :: grid
    
            real, dimension(grid%cz), intent(out) :: F 
            real, intent(in) :: Fsurf
            ! --------------------------------------------------------------------------------
    
            F(1:grid%cz) = Fsurf
        end subroutine
    
        ! --------------------------------------------------------------------------------
        subroutine set_linear_profile(F, Fsurf, Fgrad, grid)
            !< @brief set constant profile
            ! ----------------------------------------------------------------------------
            type (gridDataType), intent(in) :: grid
    
            real, dimension(grid%cz), intent(out) :: F 
            real, intent(in) :: Fsurf, Fgrad
    
            integer :: k
            ! --------------------------------------------------------------------------------
    
            do k = 1, grid%cz 
                F(k) = Fsurf + Fgrad * (grid%z(k) - (grid%zpos + grid%height)) 
            end do
        end subroutine
    
        ! --------------------------------------------------------------------------------
        subroutine set_external_profile(F, filename, grid)
            !< @brief set constant profile
            ! ----------------------------------------------------------------------------
            type (gridDataType), intent(in) :: grid
    
            real, dimension(grid%cz), intent(out) :: F
    
            integer :: num
            character(*), intent(in) :: filename
            integer :: io, status
            real :: val1, val2
    
            real, allocatable :: depth(:), Fvalue(:)
            real :: d
    
            integer :: i, k
            ! --------------------------------------------------------------------------------
    
            ! --- define number of lines in file
            open(newunit = io, file = filename, iostat = status, status ='old')
            if (status /= 0) then
                write(*, *) ' FAILURE! > unable to open file: ', trim(filename)
                return
            end if
        
            num = 0
            status = 0
            do while (status.eq.0)
                read (io, *, iostat = status) val1, val2
                num = num + 1
            enddo
            num = num - 1
        
            close(io)
    
            if (num > 0) then
                allocate(depth(num), Fvalue(num))
            endif
    
            ! --- read input data
            open(newunit = io, file = filename, iostat = status, status = 'old')
            if (status /= 0) then
                write(*, *) ' FAILURE! > unable to open file: ', trim(filename)
                return
            end if
            do i = 1, num
                read(io, *) depth(i), Fvalue(i)
            enddo
            close(io)
    
            do k = 1, grid%cz 
                d = grid%zpos + grid%height - grid%z(k) 
                call c_interp_linear(F(k), d, Fvalue, depth, num)
            end do
    
            if (num > 0) then 
                deallocate(depth, Fvalue)
            endif
        end subroutine
    
    
        ! --------------------------------------------------------------------------------
        subroutine set_config_profile(F, tag, grid, ierr)
            !< @brief set constant profile
            ! ----------------------------------------------------------------------------
            type (gridDataType), intent(in) :: grid
    
            real, dimension(grid%cz), intent(out) :: F 
            integer, intent(out) :: ierr
    
            character(len = *), intent(in) :: tag
    
            character, allocatable :: config_field(:)
            integer :: status
            
            real :: Fsurf, Fgrad
            ! --------------------------------------------------------------------------------
    
            ierr = 0        ! = OK
    
    #ifdef USE_CONFIG_PARSER
            call c_config_get_string(trim(tag)//".mode"//C_NULL_CHAR, config_field, status)
            if (status == 0) then
                ierr = 1        ! signal ERROR
                return
            end if
    
            if (trim(char_array2str(config_field)) == 'const') then
                call c_config_get_float(trim(tag)//".surface_value"//C_NULL_CHAR, Fsurf, status)
                if (status == 0) then
                    ierr = 1        ! signal ERROR
                    return
                end if
        
                call set_const_profile(F, Fsurf, grid)
            else if (trim(char_array2str(config_field)) == 'linear') then
                call c_config_get_float(trim(tag)//".surface_value"//C_NULL_CHAR, Fsurf, status)
                if (status == 0) then
                    ierr = 1        ! signal ERROR
                    return
                end if
                call c_config_get_float(trim(tag)//".grad_z"//C_NULL_CHAR, Fgrad, status)
                if (status == 0) then
                    ierr = 1        ! signal ERROR
                    return
                end if
        
                call set_linear_profile(F, Fsurf, Fgrad, grid)
            else if (trim(char_array2str(config_field)) == 'ascii') then
                call c_config_get_string(trim(tag)//".filename"//C_NULL_CHAR, config_field, status)
                if (status == 0) then
                    ierr = 1        ! signal ERROR
                    return
                end if
    
                call set_external_profile(F, char_array2str(config_field), grid)
            else
                write(*, *) ' FAILURE! > unknown initial conditions mode: ', trim(char_array2str(config_field))
                ierr = 1        ! signal ERROR
                return
            endif
    #else
            !> unable to define without config
            ierr = 1
    #endif
    
        end subroutine
    
    
    end module