public Geometry BoundaryPolygonSMeshTest(string meshPath, bool alwaysMultiPolygon = true, string extra = "") { string fileName = Path.GetFileName(meshPath); Stopwatch timer; SMeshData mesh; if (Path.GetExtension(meshPath) == ".dfsu") { DfsuFile file = DfsFileFactory.DfsuFileOpen(meshPath); timer = MeshExtensions.StartTimer(); mesh = new SMeshData(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.ToSMeshData(); } 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, "-sbnd" + extra, boundaryGeom, timer); return(boundaryGeom); }
public void InterpolateNodeTest() { string triMesh = UnitTestHelper.TestDataDir + "odense_rough.mesh"; string quadMesh = UnitTestHelper.TestDataDir + "odense_rough_quads.mesh"; // Source mesh MeshFile sourcemeshFile = MeshFile.ReadMesh(triMesh); SMeshData sourcemesh = sourcemeshFile.ToSMeshData(); sourcemesh.BuildDerivedData(); // Target mesh MeshFile targetMeshFile = MeshFile.ReadMesh(quadMesh); SMeshData targetmesh = targetMeshFile.ToSMeshData(); targetmesh.BuildDerivedData(); MeshInterpolator2D interpolator = new MeshInterpolator2D(sourcemesh, MeshValueType.Nodes); interpolator.SetTarget(targetmesh, MeshValueType.Nodes); double[] target = new double[targetmesh.NumberOfNodes]; interpolator.InterpolateNodeToTarget(sourcemesh.Z, target); Assert.False(target.Any(vv => vv == interpolator.DeleteValue)); targetMeshFile.Z = target; targetMeshFile.Write(UnitTestHelper.TestDataDir + "test_odense_rough_quads-fromTri.mesh"); }
public List <SMeshBoundary> BoundaryListSMeshTest(string meshPath) { string fileName = Path.GetFileName(meshPath); Stopwatch timer; SMeshData mesh; if (Path.GetExtension(meshPath) == ".dfsu") { DfsuFile file = DfsFileFactory.DfsuFileOpen(meshPath); timer = MeshExtensions.StartTimer(); mesh = new SMeshData(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.ToSMeshData(); } Console.Out.WriteLine("(#nodes,#elmts)=({0},{1}) ({2})", mesh.NumberOfNodes, mesh.NumberOfElements, mesh.NumberOfNodes + mesh.NumberOfElements); timer.ReportAndRestart("Create"); List <SMeshBoundary> boundaries = mesh.BuildBoundaryList(); timer.ReportAndRestart("Time "); string gpFileName = UnitTestHelper.TestDataDir + "test_" + fileName + "-bndscode.txt"; GnuPlotWriteBoundaryList(mesh, gpFileName, boundaries); return(boundaries); }
private static void DfsuBuildGeometry(string targetMeshFilename, DfsuBuilder builder) { DfsFactory factory = new DfsFactory(); if (targetMeshFilename.EndsWith(".mesh", StringComparison.OrdinalIgnoreCase)) { MeshFile target = MeshFile.ReadMesh(targetMeshFilename); // Setup header and geometry, copy from source file builder.SetNodes(target.X, target.Y, target.Z.ToFloatArray(), target.Code); builder.SetElements(target.ElementTable); builder.SetProjection(factory.CreateProjection(target.Projection)); builder.SetZUnit(eumUnit.eumUmeter); } else { DfsuFile target = DfsFileFactory.DfsuFileOpen(targetMeshFilename); // Setup header and geometry, copy from source file builder.SetNodes(target.X, target.Y, target.Z, target.Code); builder.SetElements(target.ElementTable); builder.SetProjection(target.Projection); builder.SetZUnit(eumUnit.eumUmeter); target.Close(); } }
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); } } }
public void SMeshDataOdenseQuadsTest() { string quadMesh = UnitTestHelper.TestDataDir + "odense_rough_quads.mesh"; MeshFile meshFile = MeshFile.ReadMesh(quadMesh); SMeshData mesh = meshFile.ToSMeshData(); Assert.AreEqual(535, mesh.NumberOfNodes); Assert.AreEqual(5, mesh.NodeIds[4]); Assert.AreEqual(212827.81746849261, mesh.X[4]); Assert.AreEqual(6156804.9152286667, mesh.Y[4]); Assert.AreEqual(-0.42102556956959569, mesh.Z[4]); Assert.AreEqual(1, mesh.Code[5]); Assert.AreEqual(724, mesh.NumberOfElements); Assert.AreEqual(5, mesh.ElementIds[4]); Assert.AreEqual(3, mesh.ElementTable[4].Length); Assert.AreEqual(62, mesh.ElementTable[4][0]); // Remember: Index here is zero based, while mesh file is one-based Assert.AreEqual(367, mesh.ElementTable[4][1]); Assert.AreEqual(358, mesh.ElementTable[4][2]); mesh.BuildNodeElements(); Assert.AreEqual(4, mesh.NodesElmts[4].Count); Assert.AreEqual(33, mesh.NodesElmts[4][0] + 1); Assert.AreEqual(36, mesh.NodesElmts[4][1] + 1); Assert.AreEqual(43, mesh.NodesElmts[4][2] + 1); Assert.AreEqual(58, mesh.NodesElmts[4][3] + 1); //mesh.BuildFaces(true, true, false); //int reverts = FaceRevert(mesh, mesh.Faces); //Console.Out.WriteLine("reverts: " + reverts); //mesh.Faces.Sort(FaceSortComparer); //List<MeshFace> facesOld = mesh.Faces; //mesh.BuildFaces(true, true, true); //reverts = FaceRevert(mesh, mesh.Faces); //Console.Out.WriteLine("reverts: " + reverts); //mesh.Faces.Sort(FaceSortComparer); //List<MeshFace> facesNew = mesh.Faces; //for (int i = 0; i < facesOld.Count; i++) //{ // bool ok = FaceEquals(facesOld[i], facesNew[i]); // Assert.IsTrue(ok, "Face " + i); //} //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 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); } } }
/// <summary> /// Process the incoming mesh file names /// </summary> /// <param name="files">List of mesh file names to merge</param> /// <param name="fileBoundaryCodesToRemove">List of boundary codes to remove for each mesh. Must match the size of the files argument</param> public void Process(List <string> files, List <List <int> > fileBoundaryCodesToRemove = null) { // Extent of entire domain, all meshes Extent extent = new Extent(); // Load all meshes List <MeshFile> meshes = new List <MeshFile>(files.Count); for (int i = 0; i < files.Count; i++) { MeshFile mesh = MeshFile.ReadMesh(files[i]); meshes.Add(mesh); for (int j = 0; j < mesh.NumberOfNodes; j++) { extent.Include(mesh.X[j], mesh.Y[j]); } } // grow it a littl bit, in case of rounding errors extent.XMin = extent.XMin - NodeTolerance; extent.XMax = extent.XMax + NodeTolerance; extent.YMin = extent.YMin - NodeTolerance; extent.YMax = extent.YMax + NodeTolerance; // Initialize search tree _nodeSearchTree = new QuadSearchTree(extent); // Create new mesh nodes and elements for (int i = 0; i < files.Count; i++) { int prevNodeMergeCount = NodeMergeCount; List <int> boundaryCodesToRemove = fileBoundaryCodesToRemove != null ? fileBoundaryCodesToRemove[i] : null; AddMesh(meshes[i], boundaryCodesToRemove); if (i > 0) { Console.Out.WriteLine("Mesh {0}, number of nodes merged in: {1}", i + 1, NodeMergeCount - prevNodeMergeCount); } } Console.Out.WriteLine("Total number of nodes merged in : {0}", NodeMergeCount); RemoveInternalBoundaryCodes(_code, _connectivity); // Create new mesh file string projection = meshes[0].ProjectionString; eumQuantity eumQuantity = meshes[0].EumQuantity; MeshBuilder builder = new MeshBuilder(); builder.SetNodes(_x.ToArray(), _y.ToArray(), _z.ToArray(), _code.ToArray()); builder.SetElements(_connectivity.ToArray()); builder.SetProjection(projection); builder.SetEumQuantity(eumQuantity); MeshFile newMesh = builder.CreateMesh(); MeshValidator meshValidator = new MeshValidator(); meshValidator.ValidateMesh(newMesh.X, newMesh.Y, newMesh.Code, newMesh.ElementTable); foreach (string error in meshValidator.Errors) { Console.Out.WriteLine(error); } newMesh.Write(_newMeshFileName); //------------------------------------- // Do some statistics on the mesh: // collect number of face codes for each mesh SortedDictionary <int, int[]> bcCodesStats = new SortedDictionary <int, int[]>(); List <MeshValidator> validators = new List <MeshValidator>(); for (int meshIndex = 0; meshIndex < meshes.Count; meshIndex++) { MeshFile meshFile = meshes[meshIndex]; MeshValidator validator = new MeshValidator(); validator.ValidateMesh(meshFile.X, meshFile.Y, meshFile.Code, meshFile.ElementTable); validators.Add(validator); UpdateStatistics(meshes.Count + 1, meshIndex, bcCodesStats, validator.GetFaceCodeStatistics()); } UpdateStatistics(meshes.Count + 1, meshes.Count, bcCodesStats, meshValidator.GetFaceCodeStatistics()); Console.Out.Write("---------------------"); Console.Out.Write(" Statistics of faces "); Console.Out.Write("---------------------"); Console.Out.WriteLine(""); Console.Out.Write("FaceCode |"); for (int i = 0; i < meshes.Count; i++) { Console.Out.Write(" mesh {0,2} ", i + 1); } Console.Out.Write(" | total | new mesh"); Console.Out.WriteLine(""); int[] totals = new int[meshes.Count + 2]; foreach (KeyValuePair <int, int[]> keyValuePair in bcCodesStats) { Console.Out.Write(" {0,4} |", keyValuePair.Key); int total = 0; for (int index = 0; index < keyValuePair.Value.Length - 1; index++) { int meshCodeCount = keyValuePair.Value[index]; total += meshCodeCount; totals[index] += meshCodeCount; Console.Out.Write(" {0,7} ", meshCodeCount); } totals[meshes.Count] += total; totals[meshes.Count + 1] += keyValuePair.Value.Last(); Console.Out.Write(" |{0,7} | ", total); Console.Out.Write(" {0,7} ", keyValuePair.Value.Last()); Console.Out.WriteLine(""); } Console.Out.Write(" total |"); for (int index = 0; index < meshes.Count; index++) { Console.Out.Write(" {0,7} ", totals[index]); } Console.Out.Write(" |{0,7} | ", totals[meshes.Count]); Console.Out.Write(" {0,7} ", totals[meshes.Count + 1]); Console.Out.WriteLine(""); Console.Out.Write("---------------------"); Console.Out.Write("---------------------"); Console.Out.Write("---------------------"); Console.Out.WriteLine(""); }
public void InterpolateToXYExample(bool nodeInterp) { // Source mesh string triMesh = UnitTestHelper.TestDataDir + "small.mesh"; MeshFile meshFile = MeshFile.ReadMesh(triMesh); SMeshData mesh = meshFile.ToSMeshData(); // Build derived data, required for the interpolation routines mesh.BuildDerivedData(); // Create element center Z values array double[] elmtZ = new double[meshFile.NumberOfElements]; Array.Copy(mesh.ElementZCenter, elmtZ, mesh.NumberOfElements); // Make a strong peak at element 5 - in the center of the mesh elmtZ[4] = -6; // Set up so source can be both element values and node values MeshValueType sourceType = MeshValueType.Elements | MeshValueType.Nodes; // Mesh interpolator MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh, sourceType); if (nodeInterp) { // Simpler interpolation type interpolator.ElementValueInterpolationType = MeshInterpolator2D.ElmtValueInterpolationType.NodeValues; } // Interpolate elmtZ to nodeZ double[] nodeZInterp = new double[mesh.NumberOfNodes]; interpolator.SetupElmtToNodeInterpolation(); interpolator.NodeInterpolator.Interpolate(elmtZ, nodeZInterp); // Interpolation of values one-by-one, no storing of interpolation weights Assert.AreEqual(-5.999, interpolator.InterpolateElmtToXY(0.7833, 0.531, elmtZ, nodeZInterp), 1e-3); Assert.AreEqual(-3.543, interpolator.InterpolateNodeToXY(0.7833, 0.531, nodeZInterp), 1e-3); // Add targets, to store interpolation weights interpolator.SetTargetSize(mesh.NumberOfElements + 1); interpolator.AddTarget(0.7833, 0.531); // Target at (almost) center of element 5 for (int i = 0; i < mesh.NumberOfElements; i++) { interpolator.AddTarget(mesh.ElementXCenter[i], mesh.ElementYCenter[i]); } // Array to interpolate values to double[] targetValues = new double[mesh.NumberOfElements + 1]; // Interpolate to all target points interpolator.InterpolateElmtToTarget(elmtZ, targetValues); if (!nodeInterp) { // When element+node values are used, close to peak value of 6 Assert.AreEqual(-5.999, targetValues[0], 1e-3); Assert.AreEqual(-3.8225, targetValues[1], 1e-3); for (int i = 0; i < mesh.NumberOfElements; i++) { Assert.AreEqual(elmtZ[i], targetValues[i + 1]); } } else // Using only node interpolation, the value is cut off { Assert.AreEqual(-3.543, targetValues[0], 1e-3); Assert.AreEqual(-3.649, targetValues[1], 1e-3); } // Interpolating in node Z values, matching to box center value of element. interpolator.InterpolateNodeToTarget(mesh.Z, targetValues); Assert.AreEqual(-4.376, targetValues[0], 1e-3); Assert.AreEqual(-4.376, mesh.ElementZCenter[4], 1e-3); }
/// <summary> /// Example of how to plot a mesh file. A mesh contains bottom levels in each node. /// </summary> public static void MeshTest(bool makeBmp) { DHI.Chart.Map.Chart.Init(); // Load mesh data string pathName = Path.Combine(UnitTestHelper.TestDataRoot, @"oresund.mesh"); MeshFile meshFile = MeshFile.ReadMesh(pathName); // FemGridData is data for the bottom levels, a value in each element node, used for coloring FemGridData data = new FemGridData(); data.CreateNodesAndElements(meshFile.NumberOfNodes, meshFile.NumberOfElements, meshFile.X, meshFile.Y, meshFile.Z.ToFloatArray(), meshFile.ElementTable); // Create chart DHI.Chart.Map.Chart chart = new DHI.Chart.Map.Chart(); // Add overlay that plots the bottom levels FemGridOverlay overlay = new FemGridOverlay(); overlay.SetGridData(data); overlay.EnableNiceValue = true; overlay.CreateAutoScaledRainbowPalette(); overlay.EnableIsoline = true; overlay.ColoringType = MapOverlay.EColoringType.ContinuousColoring; overlay.SetFeathering(true, 0.5f); overlay.EnableIsolineLabel = true; chart.AddOverlay(overlay); // Grab map projection of meshfile MapProjection mapProj = new MapProjection(meshFile.ProjectionString); double lonOrigin, latOrigin, eastOrigin, northOrigin; mapProj.GetOrigin(out lonOrigin, out latOrigin); mapProj.Geo2Proj(lonOrigin, latOrigin, out eastOrigin, out northOrigin); double convergence = mapProj.GetConvergence(lonOrigin, latOrigin); // Overlay adding geographical lines // Mesh is drawn in map projection coordinates GeoGridOverlay ggOverlay = new GeoGridOverlay(); ggOverlay.ReferenceProjection = meshFile.ProjectionString; ggOverlay.DisplayProjection = meshFile.ProjectionString; // Origin for mesh data is the origin of the projection ggOverlay.SetGeoOrigin(lonOrigin, latOrigin); ggOverlay.SetOrigin(eastOrigin, northOrigin); // Mesh overlay draws in map projection coordinates, so north-Y rotation is the convergence (which is zero) ggOverlay.SetNYCRotation(convergence); ggOverlay.EnableLonLatGrid = true; ggOverlay.EnableMapProjGrid = true; // DataValid must be set after changing in GeoGridOverlay ggOverlay.DataValid = true; chart.AddOverlay(ggOverlay); // Select rectangle to plot, by default the full data area MzRectangle wrect = new MzRectangle(); data.GetDataArea(wrect); // Here you may limit the area to be plotted //wrect.X0 = wrect.X0 + 20000; //wrect.Y0 = wrect.Y0 + 20000; //wrect.X1 = wrect.X0 + 30000; //wrect.Y1 = wrect.Y0 + 30000; chart.SetDataArea(wrect); chart.SetView(wrect); //chart.GetActiveCoordinateSystem().SetDrawAxis(true, true); //chart.GetActiveCoordinateSystem().EnableBorder(true); //chart.DrawGrid = true; //chart.DrawTitle = true; // Draw to bitmap double ratio = wrect.Width / (double)wrect.Height; Bitmap bmp = new Bitmap(((int)(ratio * 1024)) + 10, 1024); chart.Draw(bmp); chart.Dispose(); if (makeBmp) { string pngFilepath = Path.Combine(UnitTestHelper.TestDataRoot, @"oresundMesh.png"); bmp.Save(pngFilepath); System.Diagnostics.Process.Start(pngFilepath); } }
/// <summary> /// Create DFS2 file with iterpolated values from the 3x3 quadrangles, /// with various delete values applied in each time step. /// </summary> public void DeleteValueVisualDfs2DoTest() { string meshFileName = UnitTestHelper.TestDataDir + "small.mesh"; MeshFile file = MeshFile.ReadMesh(meshFileName); _meshVisual = file.ToSMeshData(); DfsFactory factory = new DfsFactory(); Dfs2Builder dfs2Builder = new Dfs2Builder(); dfs2Builder.SetDataType(0); dfs2Builder.SetTemporalAxis(factory.CreateTemporalEqTimeAxis(eumUnit.eumUsec, 0, 1)); dfs2Builder.SetSpatialAxis(factory.CreateAxisEqD2(eumUnit.eumUmeter, 80, 0, 0.01, 80, 0, 0.01)); dfs2Builder.SetGeographicalProjection(factory.CreateProjectionUndefined()); dfs2Builder.AddDynamicItem("DeleteValueSmooth", eumQuantity.UnDefined, DfsSimpleType.Float, DataValueType.Instantaneous); dfs2Builder.AddDynamicItem("DeleteValueBox", eumQuantity.UnDefined, DfsSimpleType.Float, DataValueType.Instantaneous); dfs2Builder.DeleteValueFloat = (float)d; dfs2Builder.CreateFile(UnitTestHelper.TestDataDir + "test_InterpTri.dfs2"); Dfs2File dfs2File = dfs2Builder.GetFile(); // Calculate interpolation weights MeshWeights[][] weights = new MeshWeights[80][]; for (int j = 0; j < 80; j++) { double y = 0.2 + 0.01 * j + 0.005; weights[j] = new MeshWeights[80]; for (int i = 0; i < 80; i++) { double x = 0.4 + 0.01 * i + 0.005; weights[j][i].QuadWeights = InterpQuadrangle.UndefinedWeights(); weights[j][i].TriWeights = InterpTriangle.UndefinedWeights(); for (int ielmt = 0; ielmt < _meshVisual.NumberOfElements; ielmt++) { var elmtNodes = _meshVisual.ElementTable[ielmt]; if (elmtNodes.Length == 4) { double x0 = _meshVisual.X[elmtNodes[0]]; double x1 = _meshVisual.X[elmtNodes[1]]; double x2 = _meshVisual.X[elmtNodes[2]]; double x3 = _meshVisual.X[elmtNodes[3]]; double y0 = _meshVisual.Y[elmtNodes[0]]; double y1 = _meshVisual.Y[elmtNodes[1]]; double y2 = _meshVisual.Y[elmtNodes[2]]; double y3 = _meshVisual.Y[elmtNodes[3]]; if (MeshExtensions.IsPointInsideQuadrangle(x, y, x0, y0, x1, y1, x2, y2, x3, y3)) { weights[j][i].ElmtIndex = ielmt; weights[j][i].QuadWeights = InterpQuadrangle.InterpolationWeights(x, y, x0, y0, x1, y1, x2, y2, x3, y3); } } else { double x0 = _meshVisual.X[elmtNodes[0]]; double x1 = _meshVisual.X[elmtNodes[1]]; double x2 = _meshVisual.X[elmtNodes[2]]; double y0 = _meshVisual.Y[elmtNodes[0]]; double y1 = _meshVisual.Y[elmtNodes[1]]; double y2 = _meshVisual.Y[elmtNodes[2]]; if (MeshExtensions.IsPointInsideTriangle(x, y, x0, y0, x1, y1, x2, y2)) { weights[j][i].ElmtIndex = ielmt; weights[j][i].TriWeights = InterpTriangle.InterpolationWeights(x, y, x0, y0, x1, y1, x2, y2); } } } } } // Original center quadrangle values double z4 = _meshVisual.Z[3]; double z6 = _meshVisual.Z[5]; double z8 = _meshVisual.Z[7]; float[] data = new float[80 * 80]; VisualDfs2Data(weights, data, z4, z6, z8, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, z6, z8, false); dfs2File.WriteItemTimeStepNext(0, data); // One delete value VisualDfs2Data(weights, data, d, z6, z8, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, d, z6, z8, false); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, d, z8, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, d, z8, false); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, z6, d, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, z6, d, false); dfs2File.WriteItemTimeStepNext(0, data); // Two adjacent delete values VisualDfs2Data(weights, data, d, d, z8, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, d, d, z8, false); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, d, d, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, z4, d, d, false); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, d, z6, d, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, d, z6, d, false); dfs2File.WriteItemTimeStepNext(0, data); // All delete values VisualDfs2Data(weights, data, d, d, d, true); dfs2File.WriteItemTimeStepNext(0, data); VisualDfs2Data(weights, data, d, d, d, false); dfs2File.WriteItemTimeStepNext(0, data); dfs2File.Close(); }