geometry.f90 Source File


This file depends on

sourcefile~~geometry.f90~~EfferentGraph sourcefile~geometry.f90 geometry.f90 sourcefile~vector.f90 vector.f90 sourcefile~geometry.f90->sourcefile~vector.f90

Files dependent on this one

sourcefile~~geometry.f90~~AfferentGraph sourcefile~geometry.f90 geometry.f90 sourcefile~cellcentercalc_test.f90 cellCenterCalc_test.f90 sourcefile~cellcentercalc_test.f90->sourcefile~geometry.f90 sourcefile~geometry_test.f90 geometry_test.f90 sourcefile~geometry_test.f90->sourcefile~geometry.f90

Contents

Source Code


Source Code

module geometry_m
    use vector_m
    implicit none
    private

    real, parameter :: delta = 1.e-6
    real, parameter :: frac_1_6 = 1./6.

    public volume_tetra, insideJudgment_tetra, insideJudgment_tetra_check
    
contains

    !>テトラの体積計算。
    function volume_tetra(vertices) result(volume)
        real, intent(in) :: vertices(3,4)
        real volume
        real, dimension(3) :: a,b,c

        a = vertices(:,2) - vertices(:,1)
        b = vertices(:,3) - vertices(:,1)
        c = vertices(:,4) - vertices(:,1)

        volume = frac_1_6 * abs(dot_product(cross_product(a, b), c))

    end function

    !>任意の点がテトラの内部にあるかどうかを判定する。
    !>点でテトラを分割したそれぞれの体積の和が、元々のテトラの体積を上回れば、点はテトラ外部にある。
    !>https://matcha-choco010.net/2018/03/14/point-in-tetrahedron/
    function insideJudgment_tetra(vertices, point) result(isInside)
        real, intent(in) :: vertices(3,4), point(3)
        real volume, vol_sum
        logical isInside

        volume = volume_tetra(vertices)
        vol_sum = partitionedVolume_sum_tetra(vertices, point)

        !点がテトラの内部にあるとき、分割体積和と元々の体積は厳密に一致するはずだが、
        !数値誤差のために少し条件を緩和する
        isInside = (abs(1. - vol_sum/volume) <= delta)

    end function

    !>点でテトラを分割したそれぞれの体積の和を求める
    function partitionedVolume_sum_tetra(vertices, point) result(vol_sum)
        real, intent(in) :: vertices(3,4), point(3)
        real vol_sum, mini_vertices(3,4)
        integer i

        vol_sum = 0.

        do i = 1, 4
            mini_vertices = vertices
            mini_vertices(:,i) = point
            vol_sum = vol_sum + volume_tetra(mini_vertices)
        end do

    end function

    subroutine insideJudgment_tetra_check(vertices, point, vol_sum, volume)
        !!テトラの内外判定の内部処理確認用サブルーチン
        real, intent(in) :: vertices(3,4), point(3)
        real, intent(out) :: volume
            !!テトラ体積
        real, intent(out) :: vol_sum
            !!分割体積和

        volume = volume_tetra(vertices)
        vol_sum = partitionedVolume_sum_tetra(vertices, point)

    end subroutine

end module geometry_m