@@ -19,7 +19,20 @@ function plot!(p::GridVisualizer, ops, sol; kwargs...)
1919Plots the operator evaluations ops of blocks in sol into the GridVisualizer.
2020
2121"""
22- function plot! (p:: GridVisualizer , ops, sol; rasterpoints = 10 , linewidth = 1 , keep = [], ncols = size (p. subplots, 2 ), do_abs = true , do_vector_plots = true , title_add = " " , kwargs... )
22+ function plot! (
23+ p:: GridVisualizer ,
24+ ops,
25+ sol;
26+ rasterpoints = 10 ,
27+ linewidth = 1 ,
28+ keep = [],
29+ ncols = size (p. subplots, 2 ),
30+ do_abs = true ,
31+ do_vector_plots = true ,
32+ title_add = " " ,
33+ average_broken_plots = false ,
34+ kwargs...
35+ )
2336 col, row, id = 0 , 1 , 0
2437 for op in ops
2538 col += 1
@@ -47,7 +60,9 @@ function plot!(p::GridVisualizer, ops, sol; rasterpoints = 10, linewidth = 1, ke
4760 else
4861 title = op[2 ] == Identity ? " $(sol[op[1 ]]. name) " : " $(op[2 ]) ($(sol[op[1 ]]. name) )"
4962 end
50- if resultdim == 1
63+ if ! average_broken_plots && is_scalar_broken_lagrange_FE (get_FEType (sol[op[1 ]]. FES))
64+ broken_scalarplot! (p[row, col], sol[op[1 ]]; title = title * title_add, kwargs... )
65+ elseif resultdim == 1
5166 GridVisualize. scalarplot! (p[row, col], sol[op[1 ]]. FES. dofgrid, view (nodevalues (sol[op[1 ]], op[2 ]; abs = false ), 1 , :), title = title * title_add; kwargs... )
5267 elseif do_abs == true
5368 GridVisualize. scalarplot! (p[row, col], sol[op[1 ]]. FES. dofgrid, view (nodevalues (sol[op[1 ]], op[2 ]; abs = true ), 1 , :), title = " |" * title * " |" * title_add; kwargs... )
@@ -71,6 +86,69 @@ function plot!(p::GridVisualizer, ops, sol; rasterpoints = 10, linewidth = 1, ke
7186 return p
7287end
7388
89+ # helper to detect broken Lagrange FES
90+ is_scalar_broken_lagrange_FE (FEType) = false
91+ is_scalar_broken_lagrange_FE (:: Type{L2P0{1}} ) = true
92+ is_scalar_broken_lagrange_FE (:: Type{L2P1{1}} ) = true
93+
94+ """
95+ broken_scalarplot!(vis, feVectorBlock; kwargs...)
96+
97+ A "broken" scalarplot of a broken finite element vector (currently only L2P0 and L2P1 are supported)
98+ Instead of averaging the discontinuous values on the grid nodes, each grid cell is plotted
99+ independently. Thus, a discontinuous plot is generated.
100+
101+ All kwargs of the calling method are transferred to the scalarplot in this method.
102+ """
103+ function broken_scalarplot! (vis, feVectorBlock:: FEVectorBlock ; kwargs... )
104+
105+ FES = feVectorBlock. FES
106+ dofgrid = FES. dofgrid
107+ dim = dim_space (dofgrid)
108+
109+ cell_nodes = dofgrid[CellNodes]
110+ cell_dofs = FES[CellDofs]
111+ coords = dofgrid[Coordinates]
112+
113+ nodes_per_cell = size (cell_nodes, 1 )
114+ all_cells = Vector {SVector{nodes_per_cell, Int32}} (undef, 0 )
115+ all_coords = Vector {SVector{dim, Float64}} (undef, 0 )
116+ all_values = Vector {Float64} (undef, 0 )
117+
118+ for i_cell in 1 : size (cell_nodes, 2 )
119+ # create a new independent cell
120+ i = nodes_per_cell * (i_cell - 1 ) + 1
121+ push! (all_cells, i: (i + nodes_per_cell - 1 ))
122+
123+ # copy the coords
124+ for n in @views cell_nodes[:, i_cell]
125+ @views push! (all_coords, coords[:, n][:])
126+ end
127+
128+ # extract values from feVector
129+ values = feVectorBlock. entries[cell_dofs[:, i_cell]]
130+ if length (values) == 1 # L2P0 !!
131+ values = fill (values[1 ], nodes_per_cell)
132+ end
133+ @views append! (all_values, values)
134+ end
135+
136+ # convert to matrices
137+ cell_matrix = Matrix {Int32} (undef, nodes_per_cell, length (all_cells))
138+ for i in 1 : size (cell_matrix, 1 ), j in 1 : size (cell_matrix, 2 )
139+ cell_matrix[i, j] = all_cells[j][i]
140+ end
141+
142+ coord_matrix = Matrix {Float64} (undef, dim, length (all_coords))
143+ for i in 1 : size (coord_matrix, 1 ), j in 1 : size (coord_matrix, 2 )
144+ coord_matrix[i, j] = all_coords[j][i]
145+ end
146+
147+ GridVisualize. scalarplot! (vis, coord_matrix, cell_matrix, all_values; kwargs... )
148+
149+ return nothing
150+ end
151+
74152
75153"""
76154````
0 commit comments