/// <summary> /// Plots all fields in <paramref name="fieldsToPlot"/> into a Tecplot file, see /// <see cref="PlotDriver.ZoneDriver.PlotZone"/>. /// </summary> public unsafe override void PlotZone(string ZoneName, double time, IEnumerable <Tuple <string, ScalarFunctionEx> > fieldsToPlot) { List <ScalarFunctionEx> fields = new List <ScalarFunctionEx>( fieldsToPlot.Select(x => x.Item2)); //for (int iKref = 0; iKref < GridDat.Grid.RefElements.Length; iKref++) { { int totalVertices = vertices.GetLength(0); if (showJumps) { totalVertices = NoOfCells * verticesPerCell; } ZoneType zoneType = GetZoneType(base.Zone_Element); WriteZoneInformation(time, zoneType, totalVertices, totalCells, ZoneName); // write grid vertices // =================== if (!showJumps) { // reconstructed mode // vertices that are at the same position are written only once double[] globalCoordinates = new double[totalVertices]; for (int d = 0; d < dimension; d++) { for (int vertex = 0; vertex < totalVertices; vertex++) { globalCoordinates[vertex] = vertices[vertex, d]; } int VIsDouble = 1; int n = globalCoordinates.Length; m_TECPLOT.TECDAT110(ref n, globalCoordinates, ref VIsDouble); } } else { // each-cell-on-its-own -- mode double[] globalCoordinates = new double[verticesPerCell]; for (int d = 0; d < dimension; d++) { for (int j = 0; j < NoOfCells; j++) { for (int i = 0; i < verticesPerCell; i++) { globalCoordinates[i] = verticeCoordinates[j, i, d]; } int VIsDouble = 1; int n = globalCoordinates.Length; m_TECPLOT.TECDAT110(ref n, globalCoordinates, ref VIsDouble); } } } // write DG field data // =================== foreach (ScalarFunctionEx field in fields) { int VIsDouble = 1; SampleField(field, showJumps); if (!showJumps) { m_TECPLOT.TECDAT110(ref totalVertices, smoothedResult, ref VIsDouble); } else { m_TECPLOT.TECDAT110(ref totalVertices, notSmoothedResult, ref VIsDouble); } } // write cells // =========== int[] permutationTable = zoneTypeToPermutationTableMap[zoneType]; if (!showJumps) { int[,] permutedConnectivity = new int[totalCells, connectivity.GetLength(1)]; for (int i = 0; i < totalCells; i++) { for (int j = 0; j < permutationTable.Length; j++) { permutedConnectivity[i, j] = 1 + connectivity[i, permutationTable[j]]; } } // hand over a pointer to the head of the multidimensional array fixed(int *permutedConnectivity_start = &permutedConnectivity[0, 0]) { m_TECPLOT.TECNOD110(permutedConnectivity_start); } } else { int[,,] permutedConnectivity = new int[NoOfCells, subdivisionsPerCell, permutationTable.Length]; for (int j = 0; j < NoOfCells; j++) { for (int jj = 0; jj < subdivisionsPerCell; jj++) { for (int i = 0; i < permutationTable.Length; i++) { permutedConnectivity[j, jj, i] = 1 + j * verticesPerCell + subdivisionTreeLeaves[jj].GlobalVerticeInd[permutationTable[i]]; } } } // hand over a pointer to the head of the multidimensional array fixed(int *permutedConnectivity_start = &permutedConnectivity[0, 0, 0]) { m_TECPLOT.TECNOD110(permutedConnectivity_start); } } } }
/// <summary> /// The beloved spaghetti style and flavor /// </summary> /// <param name="time"></param> /// <param name="fieldCount"></param> /// <param name="gridData"></param> unsafe static void PlotAsFELineSegZone(double time, int fieldCount, AggregationGridData gridData, UnsafeTECIO m_TECPLOT) { int[,] edge2LogicalCell = gridData.iGeomEdges.LogicalCellIndices; int[][] cellVerts = gridData.iGeomCells.CellVertices; int[,] edge2GeomCell = gridData.iGeomEdges.CellIndices; byte[,] edge2Face = gridData.iGeomEdges.FaceIndices; byte[] edgeTags = gridData.iGeomEdges.EdgeTags; //Find Line Connections: Each Periodic BoundaryEdge Twice List <(int Vertex0, int Vertex1)> connection = new List <(int, int)>(gridData.iLogicalEdges.Count); for (int geomEdgeIndex = 0; geomEdgeIndex < gridData.iGeomEdges.Count; ++geomEdgeIndex) { int logicalCell1 = edge2LogicalCell[geomEdgeIndex, 0]; int logicalCell2 = edge2LogicalCell[geomEdgeIndex, 1]; if (logicalCell1 != logicalCell2) { if (edge2GeomCell[geomEdgeIndex, 0] > -1) { AddEdgeToConnection(geomEdgeIndex, 0); if (edgeTags[geomEdgeIndex] >= GridCommons.FIRST_PERIODIC_BC_TAG) //Periodic Edges { AddEdgeToConnection(geomEdgeIndex, 1); } } else { AddEdgeToConnection(geomEdgeIndex, 1); } } } void AddEdgeToConnection(int edgeIndex, int sideOfEdge) { int geomCell = edge2GeomCell[edgeIndex, sideOfEdge]; int faceIndice = edge2Face[edgeIndex, sideOfEdge]; int numberOfFaces = gridData.iGeomCells.GetRefElement(0).NoOfFaces; int[] geomVertices = cellVerts[geomCell]; int vertex0 = geomVertices[faceIndice] + 1; int vertex1 = geomVertices[(faceIndice + 1) % numberOfFaces] + 1; connection.Add((vertex0, vertex1)); } //Setup Zone MultidimensionalArray vertices = ((GridData)gridData.ParentGrid).Vertices.Coordinates; int numberOfVertices = vertices.GetLength(0); int numberOfElements = connection.Count; IntPtr ptrZoneTitle = Marshal.StringToHGlobalAnsi("Grid"); int zoneTypeIndex = 1; //FELineSeg int KMax = 0, ICellMax = 0, JCellMax = 0, KCellMax = 0, NFConn = 0, FNMode = 0; int IsBlock = 1; int StrandID = 0, ParentZone = 0, ShrConn = 0; m_TECPLOT.TECZNE110(ptrZoneTitle, ref zoneTypeIndex, ref numberOfVertices, ref numberOfElements, ref KMax, ref ICellMax, ref JCellMax, ref KCellMax, ref time, ref StrandID, ref ParentZone, ref IsBlock, ref NFConn, ref FNMode, null, // No passive variables null, // All variables node-centered null, // No shared variables ref ShrConn); Marshal.FreeHGlobal(ptrZoneTitle); //Set Vertices int VIsDouble = 1; double[] globalCoordinates = new double[numberOfVertices]; for (int d = 0; d < gridData.SpatialDimension; d++) { for (int vertex = 0; vertex < numberOfVertices; vertex++) { globalCoordinates[vertex] = vertices[vertex, d]; } int n = globalCoordinates.Length; m_TECPLOT.TECDAT110(ref n, globalCoordinates, ref VIsDouble); } //Set Values double[] values = new double[numberOfVertices]; for (int i = 0; i < fieldCount; ++i) { m_TECPLOT.TECDAT110(ref numberOfVertices, values, ref VIsDouble); } //Set Connection int[,] connectionArray = new int[numberOfElements, 2]; for (int i = 0; i < numberOfElements; ++i) { connectionArray[i, 0] = connection[i].Vertex0; connectionArray[i, 1] = connection[i].Vertex1; } fixed(int *ptr = connectionArray) { m_TECPLOT.TECNOD110(ptr); } }