| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(type_square_second), | intent(in) | :: | self | |||
| type(type_dp_vector_3d), | intent(in) | :: | cartesian | |||
| type(type_dp_vector_3d), | intent(inout) | :: | normalized | |||
| logical, | intent(inout) | :: | is_in |
module subroutine is_in_square_second(self, cartesian, normalized, is_in) class(type_square_second), intent(in) :: self type(type_dp_vector_3d), intent(in) :: cartesian type(type_dp_vector_3d), intent(inout) :: normalized logical, intent(inout) :: is_in type(type_dp_vector_3d) :: r type(type_dp_vector_3d) :: coordinate 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 ! 初期化 call r%set(0.0d0, 0.0d0, 0.0d0) tol = 1.0d-15 max_iter = 1000 converged = .false. ! Newton-Raphson 法による逆写像 do iter = 1, max_iter x0 = 0.0d0 y0 = 0.0d0 do i = 1, self%get_num_nodes() coordinate = self%get_coordinate(i) x0 = x0 + self%psi(i, r) * coordinate%x y0 = y0 + self%psi(i, r) * coordinate%y end do dx = cartesian%x - x0 dy = cartesian%y - y0 if (sqrt(dx * dx + dy * dy) < tol) then converged = .true. exit end if dx_xi = self%jacobian(1, 1, r) dx_eta = self%jacobian(1, 2, r) dy_xi = self%jacobian(2, 1, r) dy_eta = self%jacobian(2, 2, r) detJ = self%jacobian_det(r) if (abs(detJ) < 1.0d-20) exit ! ヤコビ行列の特異性チェック ! Newton-Raphson 更新 r%x = r%x + (dy_eta * dx - dx_eta * dy) / detJ r%y = r%y + (-dy_xi * dx + dx_xi * dy) / detJ end do ! 最終判定:収束かつ自然座標が範囲内 is_in = converged .and. (abs(r%x) <= 1.0d0) .and. (abs(r%y) <= 1.0d0) if (is_in) normalized = r end subroutine is_in_square_second