1616 * @param {string } meshDimension - The dimension of the solution
1717 * @param {string } plotType - The type of plot
1818 * @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"
2020 */
2121export function plotSolution (
2222 solutionVector ,
@@ -25,7 +25,7 @@ export function plotSolution(
2525 meshDimension ,
2626 plotType ,
2727 plotDivId ,
28- showMesh = false // Only applicable for rectangular domains when using generateMeshFromGeometry
28+ meshType = "structured"
2929) {
3030 const { nodesXCoordinates, nodesYCoordinates } = nodesCoordinates ;
3131
@@ -65,92 +65,98 @@ export function plotSolution(
6565
6666 Plotly . newPlot ( plotDivId , [ lineData ] , layout , { responsive : true } ) ;
6767 } 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
13381 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
14189 let layout = {
142- title : `${ plotType } plot${ showMesh ? " with mesh" : "" } - ${ solverConfig } ` ,
90+ title : `${ plotType } plot ( ${ meshType } ) - ${ solverConfig } ` ,
14391 width : plotWidth ,
14492 height : plotHeight ,
14593 xaxis : { title : "x" } ,
14694 yaxis : { title : "y" } ,
95+ margin : { l : 50 , r : 50 , t : 50 , b : 50 } ,
96+ hovermode : 'closest'
14797 } ;
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+ } ;
148137
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 } ) ;
153160 }
154- Plotly . newPlot ( plotDivId , plotData , layout , { responsive : true } ) ;
155161 }
156162}
0 commit comments