module subroutine is_in_triangle_first(self, px, py, pxi, peta, is_in)
class(type_triangle_first), intent(in) :: self
real(real64), intent(in) :: px, py
real(real64), intent(inout) :: pxi, peta
logical, intent(inout) :: is_in
real(real64) :: xi, eta
real(real64) :: x0, y0
real(real64) :: dx_xi, dx_eta, dy_xi, dy_eta
real(real64) :: detJ
real(real64) :: dx, dy
integer(int32) :: iter, max_iter
real(real64) :: tol
integer(int32) :: i
logical :: converged
! 初期化
xi = 0.0d0
eta = 0.0d0
tol = 1.0d-15
max_iter = 100
converged = .false.
! Newton-Raphson 法による逆写像
do iter = 1, max_iter
x0 = 0.0d0
y0 = 0.0d0
do i = 1, self%num_nodes
x0 = x0 + self%psi(i, xi, eta) * self%x(i)%val
y0 = y0 + self%psi(i, xi, eta) * self%y(i)%val
end do
dx = px - x0
dy = py - y0
if (sqrt(dx * dx + dy * dy) < tol) then
converged = .true.
exit
end if
dx_xi = self%jacobian(1, 1, xi, eta)
dx_eta = self%jacobian(1, 2, xi, eta)
dy_xi = self%jacobian(2, 1, xi, eta)
dy_eta = self%jacobian(2, 2, xi, eta)
detJ = self%jacobian_det(xi, eta)
if (abs(detJ) < 1.0d-20) exit ! ヤコビ行列の特異性チェック
! Newton-Raphson 更新
xi = xi + (dy_eta * dx - dx_eta * dy) / detJ
eta = eta + (-dy_xi * dx + dx_xi * dy) / detJ
end do
! 最終判定:収束かつ自然座標が範囲内
is_in = converged .and. (xi >= 0.0d0) .and. (eta >= 0.0d0) .and. (xi + eta <= 1.0d0)
if (is_in) then
pxi = xi
peta = eta
end if
end subroutine is_in_triangle_first