| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=dp), | intent(in) | :: | v0(3) | |||
| real(kind=dp), | intent(in) | :: | v1(3) | |||
| real(kind=dp), | intent(in) | :: | v2(3) | |||
| type(panel_geometry_type), | intent(out) | :: | geometry | |||
| integer(kind=i32), | intent(out) | :: | status |
subroutine init_panel_geometry(v0, v1, v2, geometry, status) real(dp), intent(in) :: v0(3), v1(3), v2(3) type(panel_geometry_type), intent(out) :: geometry integer(i32), intent(out) :: status real(dp) :: edge1(3), edge2(3), cross12(3), norm_cross, lref real(dp) :: vertex_sum(3) integer :: edge, next_edge geometry = panel_geometry_type() status = panel_geometry_nonfinite if (.not. all(ieee_is_finite(v0)) .or. .not. all(ieee_is_finite(v1)) .or. & .not. all(ieee_is_finite(v2))) return geometry%vertex(:, 1) = v0 geometry%vertex(:, 2) = v1 geometry%vertex(:, 3) = v2 edge1 = v1 - v0 edge2 = v2 - v0 cross12 = cross_product(edge1, edge2) norm_cross = sqrt(sum(cross12*cross12)) lref = max(norm2(edge1), norm2(edge2), norm2(v2 - v1)) status = panel_geometry_degenerate if (lref <= 0.0_dp) return if (norm_cross <= 128.0_dp*epsilon(1.0_dp)*lref*lref) return geometry%area = 0.5_dp*norm_cross geometry%normal = cross12/norm_cross geometry%centroid = (v0 + v1 + v2)/3.0_dp do edge = 1, 3 next_edge = merge(edge + 1, 1, edge < 3) edge1 = geometry%vertex(:, next_edge) - geometry%vertex(:, edge) geometry%edge_length(edge) = sqrt(sum(edge1*edge1)) geometry%edge_outward(:, edge) = cross_product(edge1, geometry%normal)/geometry%edge_length(edge) end do geometry%moment0 = geometry%area geometry%moment1 = geometry%area*geometry%centroid vertex_sum = v0 + v1 + v2 geometry%moment2 = geometry%area/12.0_dp*( & outer_product(v0, v0) + outer_product(v1, v1) + outer_product(v2, v2) + & outer_product(vertex_sum, vertex_sum) & ) status = panel_geometry_ok end subroutine init_panel_geometry