16
16
* @param {string } meshDimension - The dimension of the solution
17
17
* @param {string } plotType - The type of plot
18
18
* @param {string } plotDivId - The id of the div where the plot will be rendered
19
- * @param {boolean } showMesh - Flag to indicate if the mesh would be rendered
19
+ * @param {string } [meshType="structured"] - Type of mesh: "structured" or "unstructured"
20
20
*/
21
21
export function plotSolution (
22
22
solutionVector ,
@@ -25,7 +25,7 @@ export function plotSolution(
25
25
meshDimension ,
26
26
plotType ,
27
27
plotDivId ,
28
- showMesh = false // Only applicable for rectangular domains when using generateMeshFromGeometry
28
+ meshType = "structured"
29
29
) {
30
30
const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates ;
31
31
@@ -65,92 +65,98 @@ export function plotSolution(
65
65
66
66
Plotly . newPlot ( plotDivId , [ lineData ] , layout , { responsive : true } ) ;
67
67
} else if ( meshDimension === "2D" && plotType === "contour" ) {
68
- // Calculate the number of nodes along the x-axis and y-axis
69
- const numNodesX = new Set ( nodesXCoordinates ) . size ;
70
- const numNodesY = new Set ( nodesYCoordinates ) . size ;
71
-
72
- // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions
73
- let reshapedXCoordinates = math . reshape ( Array . from ( nodesXCoordinates ) , [ numNodesX , numNodesY ] ) ;
74
- let reshapedYCoordinates = math . reshape ( Array . from ( nodesYCoordinates ) , [ numNodesX , numNodesY ] ) ;
75
-
76
- // Reshape the solution array to match the grid dimensions
77
- let reshapedSolution = math . reshape ( Array . from ( solutionVector ) , [ numNodesX , numNodesY ] ) ;
78
-
79
- // Transpose the reshapedSolution array to get column-wise data
80
- let transposedSolution = math . transpose ( reshapedSolution ) ;
81
-
82
- // Create an array for x-coordinates used in the contour plot
83
- let reshapedXForPlot = [ ] ;
84
- for ( let i = 0 ; i < numNodesX * numNodesY ; i += numNodesY ) {
85
- let xValue = nodesXCoordinates [ i ] ;
86
- reshapedXForPlot . push ( xValue ) ;
87
- }
88
-
89
- // Create the data structure for the contour plot
90
- let contourData = {
91
- z : transposedSolution ,
92
- type : "contour" ,
93
- contours : {
94
- coloring : "heatmap" ,
95
- } ,
96
- x : reshapedXForPlot ,
97
- y : reshapedYCoordinates [ 0 ] ,
98
- } ;
99
-
100
- // Create mesh lines for the computational grid if showMesh is true
101
- let meshData = [ ] ;
102
- if ( showMesh ) {
103
- let meshLinesX = [ ] ;
104
- let meshLinesY = [ ] ;
105
-
106
- // Horizontal mesh lines
107
- for ( let i = 0 ; i < numNodesY ; i ++ ) {
108
- meshLinesX . push ( ...reshapedXCoordinates . map ( ( row ) => row [ i ] ) , null ) ;
109
- meshLinesY . push ( ...reshapedYCoordinates . map ( ( row ) => row [ i ] ) , null ) ;
110
- }
111
-
112
- // Vertical mesh lines
113
- for ( let i = 0 ; i < numNodesX ; i ++ ) {
114
- meshLinesX . push ( ...reshapedXCoordinates [ i ] , null ) ;
115
- meshLinesY . push ( ...reshapedYCoordinates [ i ] , null ) ;
116
- }
117
-
118
- // Create the data structure for the mesh lines
119
- meshData = {
120
- x : meshLinesX ,
121
- y : meshLinesY ,
122
- mode : "lines" ,
123
- type : "scatter" ,
124
- line : {
125
- color : "palegoldenrod" ,
126
- width : 1 ,
127
- } ,
128
- showlegend : false ,
129
- } ;
130
- }
131
-
132
- // Set a fixed maximum window size for the plot
68
+ // Use the user-provided mesh type
69
+ const isStructured = meshType === "structured" ;
70
+
71
+ // For auto-detection (if needed)
72
+ const uniqueXCoords = new Set ( nodesXCoordinates ) . size ;
73
+ const uniqueYCoords = new Set ( nodesYCoordinates ) . size ;
74
+
75
+ // Extract scalar values from solution vector
76
+ let zValues = Array . isArray ( solutionVector [ 0 ] )
77
+ ? solutionVector . map ( val => val [ 0 ] )
78
+ : solutionVector ;
79
+
80
+ // Common sizing parameters for both plot types
133
81
let maxWindowWidth = Math . min ( window . innerWidth , 700 ) ;
134
- let maxPlotWidth = Math . max ( ...reshapedXForPlot ) ;
135
- let maxPlotHeight = Math . max ( ...reshapedYCoordinates [ 0 ] ) ;
136
- let zoomFactor = maxWindowWidth / maxPlotWidth ;
137
- let plotWidth = zoomFactor * maxPlotWidth ;
138
- let plotHeight = zoomFactor * maxPlotHeight ;
139
-
140
- // Set the layout for the contour plot
82
+ let maxX = Math . max ( ...nodesXCoordinates ) ;
83
+ let maxY = Math . max ( ...nodesYCoordinates ) ;
84
+ let aspectRatio = maxY / maxX ;
85
+ let plotWidth = Math . min ( maxWindowWidth , 600 ) ;
86
+ let plotHeight = plotWidth * aspectRatio * 0.8 ; // Slightly reduce height for better appearance
87
+
88
+ // Common layout properties
141
89
let layout = {
142
- title : `${ plotType } plot${ showMesh ? " with mesh" : "" } - ${ solverConfig } ` ,
90
+ title : `${ plotType } plot ( ${ meshType } ) - ${ solverConfig } ` ,
143
91
width : plotWidth ,
144
92
height : plotHeight ,
145
93
xaxis : { title : "x" } ,
146
94
yaxis : { title : "y" } ,
95
+ margin : { l : 50 , r : 50 , t : 50 , b : 50 } ,
96
+ hovermode : 'closest'
147
97
} ;
98
+
99
+ if ( isStructured ) {
100
+ // Calculate the number of nodes along the x-axis and y-axis
101
+ const numNodesX = uniqueXCoords ;
102
+ const numNodesY = uniqueYCoords ;
103
+
104
+ // Reshape the nodesXCoordinates and nodesYCoordinates arrays to match the grid dimensions
105
+ let reshapedXCoordinates = math . reshape ( Array . from ( nodesXCoordinates ) , [ numNodesX , numNodesY ] ) ;
106
+ let reshapedYCoordinates = math . reshape ( Array . from ( nodesYCoordinates ) , [ numNodesX , numNodesY ] ) ;
107
+
108
+ // Reshape the solution array to match the grid dimensions
109
+ let reshapedSolution = math . reshape ( Array . from ( solutionVector ) , [ numNodesX , numNodesY ] ) ;
110
+
111
+ // Transpose the reshapedSolution array to get column-wise data
112
+ let transposedSolution = math . transpose ( reshapedSolution ) ;
113
+
114
+ // Create an array for x-coordinates used in the contour plot
115
+ let reshapedXForPlot = [ ] ;
116
+ for ( let i = 0 ; i < numNodesX * numNodesY ; i += numNodesY ) {
117
+ let xValue = nodesXCoordinates [ i ] ;
118
+ reshapedXForPlot . push ( xValue ) ;
119
+ }
120
+
121
+ // Create the data structure for the contour plot
122
+ let contourData = {
123
+ z : transposedSolution ,
124
+ type : "contour" ,
125
+ contours : {
126
+ coloring : "heatmap" ,
127
+ showlabels : true
128
+ } ,
129
+ //colorscale: 'Viridis',
130
+ colorbar : {
131
+ title : 'Solution'
132
+ } ,
133
+ x : reshapedXForPlot ,
134
+ y : reshapedYCoordinates [ 0 ] ,
135
+ name : 'Solution Field'
136
+ } ;
148
137
149
- // Create the plot using Plotly
150
- let plotData = [ contourData ] ;
151
- if ( showMesh ) {
152
- plotData . push ( meshData ) ;
138
+ // Create the plot using Plotly
139
+ Plotly . newPlot ( plotDivId , [ contourData ] , layout , { responsive : true } ) ;
140
+ } else {
141
+ // Create an interpolated contour plot for the unstructured mesh
142
+ let contourData = {
143
+ x : nodesXCoordinates ,
144
+ y : nodesYCoordinates ,
145
+ z : zValues ,
146
+ type : 'contour' ,
147
+ contours : {
148
+ coloring : 'heatmap' ,
149
+ showlabels : true
150
+ } ,
151
+ //colorscale: 'Viridis',
152
+ colorbar : {
153
+ title : 'Solution'
154
+ } ,
155
+ name : 'Solution Field'
156
+ } ;
157
+
158
+ // Create the plot using only the contour fill
159
+ Plotly . newPlot ( plotDivId , [ contourData ] , layout , { responsive : true } ) ;
153
160
}
154
- Plotly . newPlot ( plotDivId , plotData , layout , { responsive : true } ) ;
155
161
}
156
162
}
0 commit comments