public static void Main() { Common_.BoSSSInitialize(); int nCells = 9; int nPoints = points.GetLength(0); int nFaces = owner.Length; int nInternalFaces = neighbour.Length; var g = GridServer.FOAMmesh_to_BoSSS(nCells, faces, neighbour, owner, points); Console.WriteLine(""); //var gd = new GridData(g); }
/// <summary> /// Create a BoSSS grid from an OpenFOAM mesh /// </summary> /// <param name="ierr">output, error code; on success, set to 0</param> /// <param name="faces"> /// point labels (indices) of faces, according to OpenFOAM polymesh description (array of arrays) /// </param> /// <param name="vertices_per_face"> /// number of vertices for each face /// </param> /// <param name="nCells"> /// number of cells in OpenFOAM polymesh /// </param> /// <param name="neighbour"> /// Neighbor cell labels for internal faces /// </param> /// <param name="owner"> /// for each face, the owner cell label /// </param> /// <param name="nPoints">number of points/vertices</param> /// <param name="nFaces"> /// number of faces /// </param> /// <param name="nInternalFaces"> /// number of internal faces /// </param> /// <param name="points"> /// point coordinates, array of <paramref name="nPoints"/>*3 /// </param> unsafe public GridServer( int nPoints, int nCells, int nFaces, int nInternalFaces, int **faces, int *vertices_per_face, int *neighbour, int *owner, double *points) { Common_.BoSSSInitialize(); Console.WriteLine("nPoints = {0}, nCells = {1}, nFaces = {2}, nInternalFaces = {3}", nPoints, nCells, nFaces, nInternalFaces); try { // copy data (unmanaged to managed) int[][] _faces = new int[nFaces][]; int[] _neighbour = new int[nInternalFaces]; int[] _owner = new int[nFaces]; double[,] _points = new double[nPoints, 3]; //Debug.Assert(nFaces == GridImportTest.faces.Length, "mism nFaces len"); for (int i = 0; i < nFaces; i++) { int N = vertices_per_face[i]; //Debug.Assert(N == GridImportTest.faces[i].Length, "mism nVerts face " + i); _faces[i] = new int[N]; for (int n = 0; n < N; n++) { _faces[i][n] = faces[i][n]; //Debug.Assert(_faces[i][n] == GridImportTest.faces[i][n], "mism face " + i + " vert " + n); } } //Debug.Assert(nInternalFaces == GridImportTest.neighbour.Length, "mismatch neighbour length"); for (int i = 0; i < nInternalFaces; i++) { _neighbour[i] = neighbour[i]; //Debug.Assert(_neighbour[i] == GridImportTest.neighbour[i], "neighbour " + i + " mismatch "); } for (int i = 0; i < nFaces; i++) { _owner[i] = owner[i]; //Debug.Assert(_owner[i] == GridImportTest.owner[i], "owner " + i + " mismatch "); } for (int i = 0; i < nPoints; i++) { _points[i, 0] = points[i * 3 + 0]; _points[i, 1] = points[i * 3 + 1]; _points[i, 2] = points[i * 3 + 2]; } // create BoSSS grid GridData g = FOAMmesh_to_BoSSS(nCells, _faces, _neighbour, _owner, _points); this.GridDataObject = g; } catch (Exception e) { Console.Error.WriteLine(e.GetType().FullName); Console.Error.WriteLine(e.Message); Console.Error.WriteLine(e.StackTrace); } finally { Console.WriteLine("this is C#"); } }
public static void Main() { Common_.BoSSSInitialize(); int nCells = 9; int[][] faces = new int[][] { new int[] { 1, 5, 21, 17 }, new int[] { 4, 20, 21, 5 }, new int[] { 2, 6, 22, 18 }, new int[] { 5, 21, 22, 6 }, new int[] { 6, 22, 23, 7 }, new int[] { 5, 9, 25, 21 }, new int[] { 8, 24, 25, 9 }, new int[] { 6, 10, 26, 22 }, new int[] { 9, 25, 26, 10 }, new int[] { 10, 26, 27, 11 }, new int[] { 9, 13, 29, 25 }, new int[] { 10, 14, 30, 26 }, new int[] { 12, 28, 29, 13 }, new int[] { 13, 29, 30, 14 }, new int[] { 14, 30, 31, 15 }, new int[] { 0, 16, 20, 4 }, new int[] { 4, 20, 24, 8 }, new int[] { 8, 24, 28, 12 }, new int[] { 3, 7, 23, 19 }, new int[] { 7, 11, 27, 23 }, new int[] { 11, 15, 31, 27 }, new int[] { 0, 1, 17, 16 }, new int[] { 1, 2, 18, 17 }, new int[] { 2, 3, 19, 18 }, new int[] { 0, 4, 5, 1 }, new int[] { 4, 8, 9, 5 }, new int[] { 8, 12, 13, 9 }, new int[] { 1, 5, 6, 2 }, new int[] { 5, 9, 10, 6 }, new int[] { 9, 13, 14, 10 }, new int[] { 2, 6, 7, 3 }, new int[] { 6, 10, 11, 7 }, new int[] { 10, 14, 15, 11 }, new int[] { 16, 17, 21, 20 }, new int[] { 20, 21, 25, 24 }, new int[] { 24, 25, 29, 28 }, new int[] { 17, 18, 22, 21 }, new int[] { 21, 22, 26, 25 }, new int[] { 25, 26, 30, 29 }, new int[] { 18, 19, 23, 22 }, new int[] { 22, 23, 27, 26 }, new int[] { 26, 27, 31, 30 } }; int[] neighbour = new int[] { 1, 3, 2, 4, 5, 4, 6, 5, 7, 8, 7, 8 }; int[] owner = new int[] { 0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 6, 7, 8, 0, 3, 6, 2, 5, 8, 0, 1, 2, 0, 3, 6, 1, 4, 7, 2, 5, 8, 0, 3, 6, 1, 4, 7, 2, 5, 8 }; double[,] points = new double[, ] { { 0, 0, 0 }, { 0.03333333333, 0, 0 }, { 0.06666666667, 0, 0 }, { 0.1, 0, 0 }, { 0, 0.03333333333, 0 }, { 0.03333333333, 0.03333333333, 0 }, { 0.06666666667, 0.03333333333, 0 }, { 0.1, 0.03333333333, 0 }, { 0, 0.06666666667, 0 }, { 0.03333333333, 0.06666666667, 0 }, { 0.06666666667, 0.06666666667, 0 }, { 0.1, 0.06666666667, 0 }, { 0, 0.1, 0 }, { 0.03333333333, 0.1, 0 }, { 0.06666666667, 0.1, 0 }, { 0.1, 0.1, 0 }, { 0, 0, 0.01 }, { 0.03333333333, 0, 0.01 }, { 0.06666666667, 0, 0.01 }, { 0.1, 0, 0.01 }, { 0, 0.03333333333, 0.01 }, { 0.03333333333, 0.03333333333, 0.01 }, { 0.06666666667, 0.03333333333, 0.01 }, { 0.1, 0.03333333333, 0.01 }, { 0, 0.06666666667, 0.01 }, { 0.03333333333, 0.06666666667, 0.01 }, { 0.06666666667, 0.06666666667, 0.01 }, { 0.1, 0.06666666667, 0.01 }, { 0, 0.1, 0.01 }, { 0.03333333333, 0.1, 0.01 }, { 0.06666666667, 0.1, 0.01 }, { 0.1, 0.1, 0.01 } }; Grid_.FOAMmesh_to_BoSSS(nCells, faces, neighbour, owner, points); Common_.BoSSSFinalize(); }
internal static GridData FOAMmesh_to_BoSSS(int nCells, int[][] faces, int[] neighbour, int[] owner, double[,] points) { // Checks // ====== Common_.BoSSSInitialize(); int nFaces = faces.Length; int nInternalFaces = neighbour.Length; Debug.Assert(nFaces == owner.Length); int nPoints = points.GetLength(0); if (owner.Length != faces.Length) { throw new ArgumentException("mismatch between length of faces and owner array"); } #if DEBUG // extended sanity checks for (int i = 0; i < faces.Length; i++) { int[] pts = faces[i]; foreach (int iVtx in pts) { if (i < 0) { throw new ArgumentException("negative vertex index for face " + i); } if (i >= points.GetLength(0)) { throw new ArgumentException("vertex index out-of-range for face " + i); } } if (owner[i] < 0 || owner[i] >= nCells) { throw new ArgumentException("face owner out-of-range for face " + i); } } for (int i = 0; i < neighbour.Length; i++) { if (owner[i] < 0 || owner[i] >= nCells) { throw new ArgumentException("face neighbor out-of-range for face " + i); } } #endif // Build Cells-to-Faces correlation // ================================ List <int>[] Cells2Faces = new List <int> [nCells]; for (int j = 0; j < nCells; j++) { Cells2Faces[j] = new List <int>(); } for (int iFace = 0; iFace < nFaces; iFace++) { Debug.Assert(Cells2Faces[owner[iFace]].Contains(iFace) == false); Cells2Faces[owner[iFace]].Add(iFace); } for (int iInternalFace = 0; iInternalFace < nInternalFaces; iInternalFace++) { int NeighCell = neighbour[iInternalFace]; Debug.Assert(Cells2Faces[NeighCell].Contains(iInternalFace) == false); Cells2Faces[NeighCell].Add(iInternalFace); } // convert to BoSSS grid // ===================== Cell[] bosss_cells = new Cell[nCells]; for (int iCell = 0; iCell < nCells; iCell++) { var Cell2Faces = Cells2Faces[iCell]; if (Cell2Faces.Count == 6 && !Cell2Faces.Select(iFace => faces[iFace].Length == 4).Contains(false)) { // +++++++++++++++ // found some Cube // +++++++++++++++ int[][] cube_faces = Cell2Faces.Select(iFace => faces[iFace]).ToArray(); Debug.Assert(cube_faces.Length == 6); HashSet <int> NodesUnsorted = new HashSet <int>(); foreach (int iFace in Cell2Faces) { foreach (int iPoint in faces[iFace]) { NodesUnsorted.Add(iPoint); } } if (NodesUnsorted.Count != 8) { throw new NotImplementedException("Degenerate cubes are not supported."); } // create cell Cell cl = new Cell(); bosss_cells[iCell] = cl; cl.GlobalID = iCell; cl.Type = CellType.Cube_8; cl.NodeIndices = new int[8]; cl.TransformationParams = MultidimensionalArray.Create(8, 3); // Find point indices for bottom, i.e. 'y == -1' (in ref. coordinates): cl.NodeIndices[0] = cube_faces[0][0]; cl.NodeIndices[1] = cube_faces[0][1]; cl.NodeIndices[6] = cube_faces[0][2]; cl.NodeIndices[3] = cube_faces[0][3]; // Find point indices for 'x == -1'-wall (in ref. coordinates): bool found = false; for (int iCF = 1; iCF < 6; iCF++) { found = ContainsEdge(cube_faces[iCF], cl.NodeIndices[0], cl.NodeIndices[3], out cl.NodeIndices[2], out cl.NodeIndices[7]); if (found) { break; } } if (found == false) { throw new NotSupportedException("weired cell topology in cell " + iCell + "; assuming a cube/hex;"); } // Find point indices for 'x == +1'-wall (in ref. coordinates): found = false; for (int iCF = 1; iCF < 6; iCF++) { found = ContainsEdge(cube_faces[iCF], cl.NodeIndices[1], cl.NodeIndices[6], out cl.NodeIndices[4], out cl.NodeIndices[5]); if (found) { break; } } if (found == false) { throw new NotSupportedException("weired cell topology in cell " + iCell + "; assuming a cube/hex;"); } // set point coordinates for (int i = 0; i < 8; i++) { cl.TransformationParams.SetRow(i, points.GetRow(cl.NodeIndices[i])); } // Jacobian Test JacobianTest(cl, out bool PositiveJacobianFlag, out bool NegativeJacobianFlag, out bool Linear); if (NegativeJacobianFlag) { // flip top/bottom int _0 = cl.NodeIndices[0]; int _1 = cl.NodeIndices[1]; int _6 = cl.NodeIndices[6]; int _3 = cl.NodeIndices[3]; cl.NodeIndices[0] = cl.NodeIndices[2]; cl.NodeIndices[1] = cl.NodeIndices[4]; cl.NodeIndices[6] = cl.NodeIndices[5]; cl.NodeIndices[3] = cl.NodeIndices[7]; cl.NodeIndices[2] = _0; cl.NodeIndices[4] = _1; cl.NodeIndices[5] = _6; cl.NodeIndices[7] = _3; for (int i = 0; i < 8; i++) { cl.TransformationParams.SetRow(i, points.GetRow(cl.NodeIndices[i])); } JacobianTest(cl, out PositiveJacobianFlag, out NegativeJacobianFlag, out Linear); } if (NegativeJacobianFlag || !PositiveJacobianFlag) { throw new NotSupportedException("Found degenerate Jacobian in cell " + iCell); } Debug.Assert(PositiveJacobianFlag == true); Debug.Assert(NegativeJacobianFlag == false); if (Linear) { cl.Type = CellType.Cube_Linear; cl.TransformationParams = cl.TransformationParams.ExtractSubArrayShallow(new int[] { 0, 0 }, new int[] { 3, 2 }).CloneAs(); } } else { throw new NotImplementedException("At the moment, only support for hex cells."); } } // create BoSSS grid // ================== GridCommons grd = new GridCommons(new RefElement[] { Cube.Instance }, new RefElement[] { Square.Instance }) { Cells = bosss_cells, Description = "imported form OpenFOAM" }; var gDat = new GridData(grd); return(gDat); }