@@ -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