public Geometry BoundaryPolygonMeshTest(string meshPath, bool alwaysMultiPolygon = true, string extra = "") { string fileName = Path.GetFileName(meshPath); Stopwatch timer; MeshData mesh; if (Path.GetExtension(meshPath) == ".dfsu") { DfsuFile file = DfsFileFactory.DfsuFileOpen(meshPath); timer = MeshExtensions.StartTimer(); mesh = new MeshData(file.Projection.WKTString, file.NodeIds, file.X, file.Y, file.Z.ToDoubleArray(), file.Code, file.ElementIds, file.ElementType, file.ElementTable.ToZeroBased()); file.Close(); } else { MeshFile meshFile = MeshFile.ReadMesh(meshPath); timer = MeshExtensions.StartTimer(); mesh = meshFile.ToMeshData(); } Console.Out.WriteLine("(#nodes,#elmts)=({0},{1}) ({2})", mesh.NumberOfNodes, mesh.NumberOfElements, mesh.NumberOfNodes + mesh.NumberOfElements); timer.ReportAndRestart("Create "); Geometry boundaryGeom = mesh.BuildBoundaryGeometry(alwaysMultiPolygon); timer.ReportAndRestart("Build "); BoundaryPolygonWriter(fileName, "-bnd" + extra, boundaryGeom, timer); return(boundaryGeom); }
public List <MeshBoundary> BoundaryListMeshTest(string meshPath) { string fileName = Path.GetFileName(meshPath); Stopwatch timer; MeshData mesh; if (Path.GetExtension(meshPath) == ".dfsu") { DfsuFile file = DfsFileFactory.DfsuFileOpen(meshPath); timer = MeshExtensions.StartTimer(); mesh = new MeshData(file.Projection.WKTString, file.NodeIds, file.X, file.Y, file.Z.ToDoubleArray(), file.Code, file.ElementIds, file.ElementType, file.ElementTable.ToZeroBased()); file.Close(); } else { MeshFile meshFile = MeshFile.ReadMesh(meshPath); timer = MeshExtensions.StartTimer(); mesh = meshFile.ToMeshData(); } Console.Out.WriteLine("(#nodes,#elmts)=({0},{1}) ({2})", mesh.NumberOfNodes, mesh.NumberOfElements, mesh.NumberOfNodes + mesh.NumberOfElements); timer.ReportAndRestart("Create"); List <MeshBoundary> boundaries = mesh.BuildBoundaryList(); timer.ReportAndRestart("Time "); string gpFileName = UnitTestHelper.TestDataDir + "test_" + fileName + "-bndcode.txt"; GnuPlotWriteBoundaryList(gpFileName, boundaries); return(boundaries); }
public void NodeInterpolationTest(string meshFileName, CircularValueTypes cvt = CircularValueTypes.Normal) { // Source mesh MeshFile meshFile = MeshFile.ReadMesh(meshFileName); MeshData mesh = meshFile.ToMeshData(); // Allow for extrapolation on boundary nodes (disable clipping) MeshNodeInterpolation interpolation = new MeshNodeInterpolation(mesh) { AllowExtrapolation = true, }; interpolation.Setup(); Interpolator nodeInterpolator = interpolation.NodeInterpolator; nodeInterpolator.CircularType = cvt; // Find reference x and y value as the smallest x and y value double xMin = mesh.Nodes.Select(mn => mn.X).Min(); double xMax = mesh.Nodes.Select(mn => mn.X).Max(); double yMin = mesh.Nodes.Select(mn => mn.Y).Min(); double yMax = mesh.Nodes.Select(mn => mn.Y).Max(); // Function over the (x,y) plane. Func <double, double, double> function = ValueFunction(cvt, xMin, yMin, xMax, yMax); // Calculate element center values double[] elmtVals = new double[mesh.Elements.Count]; for (int i = 0; i < mesh.Elements.Count; i++) { MeshElement elmt = mesh.Elements[i]; elmtVals[i] = function(elmt.XCenter, elmt.YCenter); } // Write out bounds, to check we got things right Console.Out.WriteLine("{0,10} (min,max) = ({1},{2})", cvt, elmtVals.Min(), elmtVals.Max()); // Interpolate to nodes double[] nodeValues = new double[mesh.Nodes.Count]; nodeInterpolator.Interpolate(elmtVals, nodeValues); // Check node values for (int i = 0; i < mesh.Nodes.Count; i++) { MeshNode node = mesh.Nodes[i]; double exactValue = function(node.X, node.Y); double interpValue = nodeValues[i]; double diff = exactValue - interpValue; // It can only extrapolate when there is at least three elements per node. // When there is two or less elements, the inverse distance weighting takes over // and the results are not correct, so we skip the check here. if (node.Elements.Count > 2 && diff > 1e-6) { string msg = string.Format("{0,2} {6}: {1}-{2}={3} ({4},{5})", i, exactValue, interpValue, diff, node.X, node.Y, node.Elements.Count); Console.Out.WriteLine(msg); Assert.Fail(msg); } } }
/// <summary> /// Create <see cref="IMeshDataInfo"/>, depending on <paramref name="smesh"/> flag. /// </summary> public static IMeshDataInfo ToMeshData(this MeshFile file, bool smesh) { if (smesh) { return(file.ToSMeshData()); } return(file.ToMeshData()); }
public void MeshDataOdenseQuadsTest() { string quadMesh = UnitTestHelper.TestDataDir + "odense_rough_quads.mesh"; MeshFile meshFile = MeshFile.ReadMesh(quadMesh); MeshData mesh = meshFile.ToMeshData(); Assert.AreEqual(535, mesh.Nodes.Count); Assert.AreEqual(4, mesh.Nodes[4].Index); Assert.AreEqual(5, mesh.Nodes[4].Id); Assert.AreEqual(212827.81746849261, mesh.Nodes[4].X); Assert.AreEqual(6156804.9152286667, mesh.Nodes[4].Y); Assert.AreEqual(-0.42102556956959569, mesh.Nodes[4].Z); Assert.AreEqual(1, mesh.Nodes[5].Code); Assert.AreEqual(724, mesh.Elements.Count); Assert.AreEqual(4, mesh.Elements[4].Index); Assert.AreEqual(5, mesh.Elements[4].Id); Assert.AreEqual(3, mesh.Elements[4].Nodes.Count); Assert.AreEqual(62, mesh.Elements[4].Nodes[0].Index); // Remember: Index here is zero based, while mesh file is one-based Assert.AreEqual(367, mesh.Elements[4].Nodes[1].Index); Assert.AreEqual(358, mesh.Elements[4].Nodes[2].Index); mesh.BuildNodeElements(); Assert.AreEqual(4, mesh.Nodes[4].Elements.Count); Assert.AreEqual(33, mesh.Nodes[4].Elements[0].Id); Assert.AreEqual(36, mesh.Nodes[4].Elements[1].Id); Assert.AreEqual(43, mesh.Nodes[4].Elements[2].Id); Assert.AreEqual(58, mesh.Nodes[4].Elements[3].Id); mesh.BuildFaces(true); FaceRevert(mesh, mesh.Faces); mesh.Faces.Sort(FaceSortComparer); Assert.AreEqual(1259, mesh.Faces.Count); Assert.AreEqual(1, mesh.Faces[0].FromNode.Id); Assert.AreEqual(42, mesh.Faces[0].ToNode.Id); Assert.AreEqual(1, mesh.Faces[1].FromNode.Id); Assert.AreEqual(251, mesh.Faces[1].ToNode.Id); Assert.AreEqual(1, mesh.Faces[2].FromNode.Id); Assert.AreEqual(309, mesh.Faces[2].ToNode.Id); int ind = mesh.Faces.FindIndex(mf => mf.FromNode.Id == 68); Assert.AreEqual(202, ind); Assert.AreEqual(68, mesh.Faces[ind].FromNode.Id); Assert.AreEqual(43, mesh.Faces[ind].ToNode.Id); Assert.AreEqual(1, mesh.Faces[ind].Code); Assert.AreEqual(366, mesh.Faces[ind].LeftElement.Id); Assert.AreEqual(null, mesh.Faces[ind].RightElement); }
public void MeshBoundaryToFileTest() { string triMesh = UnitTestHelper.TestDataDir + "odense_rough.mesh"; MeshFile meshFile = MeshFile.ReadMesh(triMesh); MeshData mesh = meshFile.ToMeshData(); List <MeshBoundary> boundaries = MeshBoundary.BuildBoundaryList(mesh); Assert.AreEqual(2, boundaries.Count); Assert.AreEqual(1, boundaries[0].Code); Assert.AreEqual(2, boundaries[1].Code); Assert.AreEqual(2, boundaries[0].Segments.Count); Assert.AreEqual(1, boundaries[1].Segments.Count); Assert.AreEqual(9, boundaries[1].Segments[0].Count); // First node of the first code-1 boundary segment is the last node of the code-2 boundary segment Assert.IsTrue(boundaries[0].Segments[0][0].FromNode == boundaries[1].Segments[0].Last().ToNode); Assert.IsTrue(boundaries[0].Segments[0].Last().ToNode == boundaries[1].Segments[0][0].FromNode); StreamWriter writer = new StreamWriter(UnitTestHelper.TestDataDir + "out_odense_rough-bnd.txt"); foreach (MeshBoundary meshBoundary in boundaries) { writer.WriteLine("# " + meshBoundary.Code); foreach (List <MeshFace> segment in meshBoundary.Segments) { writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1}", segment[0].FromNode.X, segment[0].FromNode.Y)); foreach (MeshFace face in segment) { writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1}", face.ToNode.X, face.ToNode.Y)); } writer.WriteLine(""); } writer.WriteLine(""); } writer.Close(); }
public void InterpolateElementValuesToXYExample() { // Source mesh string triMesh = UnitTestHelper.TestDataDir + "odense_rough.mesh"; MeshFile meshFile = MeshFile.ReadMesh(triMesh); MeshData mesh = meshFile.ToMeshData(); mesh.BuildDerivedData(); // Element center values - usually read from dfsu file - here // we just calculate some arbitrary linear function of (x,y) double[] sourceValues = new double[meshFile.NumberOfElements]; for (int i = 0; i < meshFile.NumberOfElements; i++) { sourceValues[i] = 2 * mesh.Elements[i].XCenter + mesh.Elements[i].YCenter; } // Mesh interpolator MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh, MeshValueType.Elements); // Coordinates to interpolate values to interpolator.SetTargetSize(3); interpolator.AddTarget(216600, 6159900); interpolator.AddTarget(216700, 6159900); interpolator.AddTarget(216700, 6160000); // Array to interpolate values to double[] targetValues = new double[3]; // Interpolate element values to target values interpolator.InterpolateElmtToTarget(sourceValues, targetValues); // Test that values are really 2*x+y Assert.AreEqual(2 * 216600 + 6159900, targetValues[0], 1e-6); Assert.AreEqual(2 * 216700 + 6159900, targetValues[1], 1e-6); Assert.AreEqual(2 * 216700 + 6160000, targetValues[2], 1e-6); }
public void InterpolationTest(string sourceMeshFileName, string targetMeshFileName, CircularValueTypes cvt = CircularValueTypes.Normal) { // Source mesh MeshFile meshFile = MeshFile.ReadMesh(sourceMeshFileName); MeshData mesh = meshFile.ToMeshData(); mesh.BuildDerivedData(); // Mesh to interpolate to MeshFile targetFile = MeshFile.ReadMesh(targetMeshFileName); MeshData targetmesh = targetFile.ToMeshData(); // Setup interpolator MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh) { CircularType = cvt, AllowExtrapolation = true }; interpolator.SetupNodeInterpolation(); interpolator.SetTarget(targetmesh); // Find reference x and y value as the smallest x and y value double xMin = mesh.Nodes.Select(mn => mn.X).Min(); double xMax = mesh.Nodes.Select(mn => mn.X).Max(); double yMin = mesh.Nodes.Select(mn => mn.Y).Min(); double yMax = mesh.Nodes.Select(mn => mn.Y).Max(); // Function over the (x,y) plane. Func <double, double, double> function = ValueFunction(cvt, xMin, yMin, xMax, yMax); // Calculate element center values of function double[] elmtVals = new double[mesh.Elements.Count]; for (int i = 0; i < mesh.Elements.Count; i++) { MeshElement elmt = mesh.Elements[i]; elmtVals[i] = function(elmt.XCenter, elmt.YCenter); } // Write out bounds, to check we got things right Console.Out.WriteLine("{0,10} (min,max) = ({1},{2})", cvt, elmtVals.Min(), elmtVals.Max()); // Interpolate to nodes double[] targetValues = new double[targetmesh.Elements.Count]; interpolator.InterpolateToTarget(elmtVals, targetValues); // Check node values for (int i = 0; i < targetmesh.Elements.Count; i++) { MeshElement targetElmt = targetmesh.Elements[i]; double exactValue = function(targetElmt.XCenter, targetElmt.YCenter); double interpValue = targetValues[i]; double diff = exactValue - interpValue; // Check if target element has a boundary node. // Nodes on the boundary may not have correctly interpolated value due to // inverse distance interpolation on the boundary, and hence also interpolation // to target element value will not be exact. So only check on those elements that are // fully internal (no boundary nodes). bool internalElmt = targetElmt.Nodes.Select(node => node.Code).All(code => code == 0); if (internalElmt && diff > 1e-6 * Math.Max(Math.Abs(exactValue), 1)) { string msg = string.Format("{0,2} : {1}-{2}={3} ({4},{5})", i, exactValue, interpValue, diff, targetElmt.XCenter, targetElmt.YCenter); Console.Out.WriteLine(msg); Assert.Fail(msg); } } }