vector_ops.F90 Source File


Files dependent on this one

sourcefile~~vector_ops.f90~~AfferentGraph sourcefile~vector_ops.f90 vector_ops.F90 sourcefile~linalg.f90 linalg.F90 sourcefile~linalg.f90->sourcefile~vector_ops.f90 sourcefile~calculate.f90 calculate.F90 sourcefile~calculate.f90->sourcefile~linalg.f90 sourcefile~hydraulic_assemble.f90 hydraulic_assemble.F90 sourcefile~hydraulic_assemble.f90->sourcefile~calculate.f90 sourcefile~control.f90 control.F90 sourcefile~hydraulic_assemble.f90->sourcefile~control.f90 sourcefile~properties.f90 properties.F90 sourcefile~hydraulic_assemble.f90->sourcefile~properties.f90 sourcefile~hydraulic_interface.f90 hydraulic_interface.F90 sourcefile~hydraulic_interface.f90->sourcefile~calculate.f90 sourcefile~hydraulic_interface.f90->sourcefile~hydraulic_assemble.f90 sourcefile~hydraulic_interface.f90->sourcefile~control.f90 sourcefile~hydraulic_interface.f90->sourcefile~properties.f90 sourcefile~iteration.f90 iteration.F90 sourcefile~iteration.f90->sourcefile~calculate.f90 sourcefile~materials_manager.f90 materials_manager.F90 sourcefile~materials_manager.f90->sourcefile~calculate.f90 sourcefile~properties_manager.f90 properties_manager.F90 sourcefile~properties_manager.f90->sourcefile~calculate.f90 sourcefile~properties_manager.f90->sourcefile~materials_manager.f90 sourcefile~properties_manager.f90->sourcefile~control.f90 sourcefile~thermal_interface.f90 thermal_interface.F90 sourcefile~thermal_interface.f90->sourcefile~calculate.f90 sourcefile~thermal_interface.f90->sourcefile~control.f90 sourcefile~thermal_interface.f90->sourcefile~properties.f90 sourcefile~control.f90->sourcefile~iteration.f90 sourcefile~hydraulic.f90 hydraulic.F90 sourcefile~hydraulic.f90->sourcefile~hydraulic_interface.f90 sourcefile~hydraulic_crs.f90 hydraulic_crs.F90 sourcefile~hydraulic_crs.f90->sourcefile~hydraulic_interface.f90 sourcefile~properties.f90->sourcefile~materials_manager.f90 sourcefile~properties.f90->sourcefile~properties_manager.f90 sourcefile~thermal.f90 thermal.F90 sourcefile~thermal.f90->sourcefile~thermal_interface.f90 sourcefile~thermal_crs.f90 thermal_crs.F90 sourcefile~thermal_crs.f90->sourcefile~thermal_interface.f90 sourcefile~ftdss.f90 ftdss.F90 sourcefile~ftdss.f90->sourcefile~control.f90 sourcefile~ftdss.f90->sourcefile~hydraulic.f90 sourcefile~ftdss.f90->sourcefile~properties.f90 sourcefile~ftdss.f90->sourcefile~thermal.f90 sourcefile~output.f90 output.F90 sourcefile~ftdss.f90->sourcefile~output.f90 sourcefile~output_interface.f90 output_interface.F90 sourcefile~output_interface.f90->sourcefile~control.f90 sourcefile~output_interface.f90->sourcefile~properties.f90 sourcefile~output.f90->sourcefile~output_interface.f90 sourcefile~output_base.f90 output_base.F90 sourcefile~output_base.f90->sourcefile~output_interface.f90 sourcefile~output_observation.f90 output_observation.F90 sourcefile~output_observation.f90->sourcefile~output_interface.f90 sourcefile~output_overall_base.f90 output_overall_base.F90 sourcefile~output_overall_base.f90->sourcefile~output_interface.f90 sourcefile~output_overall_vtk.f90 output_overall_vtk.F90 sourcefile~output_overall_vtk.f90->sourcefile~output_interface.f90 sourcefile~output_overall_vtu.f90 output_overall_vtu.F90 sourcefile~output_overall_vtu.f90->sourcefile~output_interface.f90 sourcefile~output_system_logger.f90 output_system_logger.F90 sourcefile~output_system_logger.f90->sourcefile~output_interface.f90

Source Code

module calculate_linalg_vector_ops
!$  use omp_lib
    use, intrinsic :: iso_fortran_env, only: int32, real64
    implicit none
    private
    ! int32をサイズ指定に使用します。
#ifdef _MKL
    include "mkl_blas.fi"
#endif

    public :: norm_1
    public :: norm_2
    public :: norm_inf
    public :: dot

contains

    ! L1 ノルム
    function norm_1(x) result(norm)
        real(real64), intent(in) :: x(:)
        real(real64) :: norm
#ifdef _MKL
        norm = dasum(int(size(x), int32), x, 1)
#else
        norm = sum(abs(x))
#endif
    end function norm_1

    ! L2 ノルム
    function norm_2(x) result(norm)
        real(real64), intent(in) :: x(:)
        real(real64) :: norm
#ifdef _MKL
        norm = dnrm2(int(size(x), int32), x, 1)
#else
        norm = norm2(x)
#endif
    end function norm_2

    ! L∞ ノルム (無限大ノルム)
    function norm_inf(x) result(norm)
        real(real64), intent(in) :: x(:)
        real(real64) :: norm
#ifdef _MKL
        if (size(x) > 0) then
            norm = abs(x(idamax(int(size(x), int32), x, 1)))
        else
            norm = 0.0d0
        end if
#else
        norm = maxval(abs(x))
#endif
    end function norm_inf

    ! 内積
    function dot(x, y) result(prod)
        real(real64), intent(in) :: x(:)
        real(real64), intent(in) :: y(:)
        real(real64) :: prod

        ! 配列のサイズが異なる場合はエラーとして停止
        if (size(x) /= size(y)) then
            write (*, '(A)') "Error: dot - array sizes do not match."
            error stop 1
        end if

#ifdef _MKL
        prod = ddot(int(size(x), int32), x, 1, y, 1)
#else
        ! 手動ループやOpenMPよりも、dot_product組込み関数が推奨される
        prod = dot_product(x, y)
#endif
    end function dot

end module calculate_linalg_vector_ops