Skip to content

Commit b37fe73

Browse files
ranochagithub-actions[bot]sloede
authored
improve performance of unstructured_3d_to_1d_curve (#2318)
* improve performance of unstructured_3d_to_1d_curve * format Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Michael Schlottke-Lakemper <[email protected]>
1 parent e0ee05b commit b37fe73

File tree

1 file changed

+61
-37
lines changed

1 file changed

+61
-37
lines changed

src/visualization/utilities.jl

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -817,9 +817,11 @@ function unstructured_2d_to_1d_curve(original_nodes, unstructured_data, nvisnode
817817

818818
# Iterate over all found elements.
819819
for element in 1:n_points_curve
820-
min_coordinate = get_point(original_nodes, 1, 1, element_ids[element])
820+
element_id = element_ids[element]
821+
min_coordinate = get_point(original_nodes, 1, 1,
822+
element_id)
821823
max_coordinate = get_point(original_nodes, n_nodes, n_nodes,
822-
element_ids[element])
824+
element_id)
823825
element_length = max_coordinate - min_coordinate
824826

825827
normalized_coordinates = (get_point(curve, element) - min_coordinate) /
@@ -834,16 +836,17 @@ function unstructured_2d_to_1d_curve(original_nodes, unstructured_data, nvisnode
834836
normalized_coordinates[2], baryweights_in)
835837
for v in 1:n_variables
836838
for i in 1:n_nodes
837-
element_id = element_ids[element]
838-
let res = zero(eltype(temp_data))
839-
for n in 1:n_nodes
840-
res += vandermonde_y[n] * unstructured_data[i, n, element_id, v]
841-
end
842-
temp_data[i, element, v] = res
839+
res_i = zero(eltype(temp_data))
840+
for n in 1:n_nodes
841+
res_i += vandermonde_y[n] * unstructured_data[i, n, element_id, v]
843842
end
843+
temp_data[i, element, v] = res_i
844844
end
845-
data_on_curve[element, v] = dot(vandermonde_x,
846-
view(temp_data, :, element, v))
845+
res_v = zero(eltype(data_on_curve))
846+
for n in 1:n_nodes
847+
res_v += vandermonde_x[n] * temp_data[n, element, v]
848+
end
849+
data_on_curve[element, v] = res_v
847850
end
848851
end
849852

@@ -911,16 +914,22 @@ function unstructured_3d_to_1d_curve(original_nodes, unstructured_data, nvisnode
911914
n_points_curve = size(curve)[2]
912915
n_nodes, _, _, n_elements, n_variables = size(unstructured_data)
913916
nodes_in, _ = gauss_lobatto_nodes_weights(n_nodes)
917+
baryweights_in = barycentric_weights(nodes_in)
918+
919+
# Utility function to extract points as `SVector`s
920+
get_point(data, idx...) = SVector(data[1, idx...],
921+
data[2, idx...],
922+
data[3, idx...])
914923

915924
# Check if input is correct.
916-
min = original_nodes[:, 1, 1, 1, 1]
917-
max = max_coordinate = original_nodes[:, n_nodes, n_nodes, n_nodes, n_elements]
925+
min = get_point(original_nodes, 1, 1, 1, 1)
926+
max = get_point(original_nodes, n_nodes, n_nodes, n_nodes, n_elements)
918927
@assert size(curve)==(3, n_points_curve) "Coordinates along curve must be 3xn dimensional."
919928
for element in 1:n_points_curve
920-
@assert (prod(vcat(curve[:, n_points_curve] .>= min,
921-
curve[:, n_points_curve]
922-
.<=
923-
max))) "Some coordinates from `curve` are outside of the domain.."
929+
p = get_point(curve, element)
930+
if any(p .< min) || any(p .> max)
931+
throw(DomainError("Some coordinates from `curve` are outside of the domain."))
932+
end
924933
end
925934

926935
# Set nodes according to the length of the curve.
@@ -933,39 +942,54 @@ function unstructured_3d_to_1d_curve(original_nodes, unstructured_data, nvisnode
933942
# For each coordinate find the corresponding element with its id.
934943
element_ids = get_elements_by_coordinates(curve, mesh, solver, cache)
935944

945+
# These Vandermonde matrices are really 1×n_nodes matrices, i.e.,
946+
# row vectors. We allocate memory here to improve performance.
947+
vandermonde_x = polynomial_interpolation_matrix(nodes_in, zero(eltype(curve)))
948+
vandermonde_y = similar(vandermonde_x)
949+
vandermonde_z = similar(vandermonde_x)
950+
936951
# Iterate over all found elements.
937952
for element in 1:n_points_curve
938-
min_coordinate = original_nodes[:, 1, 1, 1, element_ids[element]]
939-
max_coordinate = original_nodes[:, n_nodes, n_nodes, n_nodes,
940-
element_ids[element]]
953+
element_id = element_ids[element]
954+
min_coordinate = get_point(original_nodes, 1, 1, 1,
955+
element_id)
956+
max_coordinate = get_point(original_nodes, n_nodes, n_nodes, n_nodes,
957+
element_id)
941958
element_length = max_coordinate - min_coordinate
942959

943-
normalized_coordinates = (curve[:, element] - min_coordinate) /
960+
normalized_coordinates = (get_point(curve, element) - min_coordinate) /
944961
element_length[1] * 2 .- 1
945962

946963
# Interpolate to a single point in each element.
947-
vandermonde_x = polynomial_interpolation_matrix(nodes_in,
948-
normalized_coordinates[1])
949-
vandermonde_y = polynomial_interpolation_matrix(nodes_in,
950-
normalized_coordinates[2])
951-
vandermonde_z = polynomial_interpolation_matrix(nodes_in,
952-
normalized_coordinates[3])
964+
# These Vandermonde matrices are really 1×n_nodes matrices, i.e.,
965+
# row vectors.
966+
polynomial_interpolation_matrix!(vandermonde_x, nodes_in,
967+
normalized_coordinates[1], baryweights_in)
968+
polynomial_interpolation_matrix!(vandermonde_y, nodes_in,
969+
normalized_coordinates[2], baryweights_in)
970+
polynomial_interpolation_matrix!(vandermonde_z, nodes_in,
971+
normalized_coordinates[3], baryweights_in)
953972
for v in 1:n_variables
954973
for i in 1:n_nodes
955974
for ii in 1:n_nodes
956-
temp_data[i, ii, element, v] = (vandermonde_z * unstructured_data[i,
957-
ii,
958-
:,
959-
element_ids[element],
960-
v])[1]
975+
res_ii = zero(eltype(temp_data))
976+
for n in 1:n_nodes
977+
res_ii += vandermonde_z[n] *
978+
unstructured_data[i, ii, n, element_id, v]
979+
end
980+
temp_data[i, ii, element, v] = res_ii
981+
end
982+
res_i = zero(eltype(temp_data))
983+
for n in 1:n_nodes
984+
res_i += vandermonde_y[n] * temp_data[i, n, element, v]
961985
end
962-
temp_data[i, n_nodes + 1, element, v] = (vandermonde_y * temp_data[i,
963-
1:n_nodes,
964-
element,
965-
v])[1]
986+
temp_data[i, n_nodes + 1, element, v] = res_i
987+
end
988+
res_v = zero(eltype(temp_data))
989+
for n in 1:n_nodes
990+
res_v += vandermonde_x[n] * temp_data[n, n_nodes + 1, element, v]
966991
end
967-
data_on_curve[element, v] = (vandermonde_x * temp_data[:, n_nodes + 1,
968-
element, v])[1]
992+
data_on_curve[element, v] = res_v
969993
end
970994
end
971995

0 commit comments

Comments
 (0)