示例#1
0
        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);
        }
示例#2
0
        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();
            }
        }
示例#3
0
        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);
        }
示例#4
0
        private IMeshDataInfo GetMesh(string dfsufilepath, bool smesh)
        {
            IMeshDataInfo mesh;

            DfsuFile file = DfsFileFactory.DfsuFileOpen(dfsufilepath);

            if (smesh)
            {
                mesh = new SMeshData(file.Projection.WKTString, file.NodeIds, file.X, file.Y, file.Z.ToDoubleArray(),
                                     file.Code, file.ElementIds, file.ElementType, file.ElementTable.ToZeroBased());
                return(mesh);
            }
            else
            {
                mesh = new MeshData(file.Projection.WKTString, file.NodeIds, file.X, file.Y, file.Z.ToDoubleArray(),
                                    file.Code, file.ElementIds, file.ElementType, file.ElementTable.ToZeroBased());
                return(mesh);
            }
        }
示例#5
0
        /// <summary>
        /// Interpolate values from <paramref name="sourceFilename"/> to mesh
        /// defined by <paramref name="targetMeshFilename"/>, and store it in
        /// <paramref name="targetFilename"/>
        /// </summary>
        /// <param name="sourceFilename">Source data for interpolation</param>
        /// <param name="targetMeshFilename">Target mesh to interpolate to. Can be a mesh or dfsu file</param>
        /// <param name="targetFilename">File to store interpolated data to</param>
        public static void Interpolate(string sourceFilename, string targetMeshFilename, string targetFilename)
        {
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            DfsuFile sourceDfsu = DfsFileFactory.DfsuFileOpen(sourceFilename);

            DfsuBuilder builder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);

            DfsuBuildGeometry(targetMeshFilename, builder);
            builder.SetTimeInfo(sourceDfsu.StartDateTime, sourceDfsu.TimeStepInSeconds);

            // Add dynamic items, copying from source
            foreach (IDfsSimpleDynamicItemInfo itemInfo in sourceDfsu.ItemInfo)
            {
                builder.AddDynamicItem(itemInfo.Name, itemInfo.Quantity);
            }

            DfsuFile targetDfsu = builder.CreateFile(targetFilename);

            watch.Stop();
            Console.Out.WriteLine("Create File : " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();


            SMeshData sourceMesh = Create(sourceDfsu);
            SMeshData targetMesh = Create(targetDfsu);

            sourceMesh.BuildDerivedData();


            watch.Stop();
            Console.Out.WriteLine("Build mesh  : " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();

            MeshInterpolator2D interpolator = new MeshInterpolator2D(sourceMesh, MeshValueType.Elements)
            {
                DeleteValue      = sourceDfsu.DeleteValueFloat,
                DeleteValueFloat = sourceDfsu.DeleteValueFloat,
                //AllowExtrapolation = true,
            };

            interpolator.SetTarget(targetMesh, MeshValueType.Elements);

            watch.Stop();
            Console.Out.WriteLine("Interpolator: " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();

            // Temporary, interpolated target-data
            float[] targetData = new float[targetDfsu.NumberOfElements];

            // Add data for all item-timesteps, copying from source, interpolating
            IDfsItemData <float> sourceData;

            while (null != (sourceData = sourceDfsu.ReadItemTimeStepNext() as IDfsItemData <float>))
            {
                interpolator.InterpolateElmtToTarget(sourceData.Data, targetData);
                targetDfsu.WriteItemTimeStepNext(sourceData.Time, targetData);
            }
            watch.Stop();
            Console.Out.WriteLine("Interpolate : " + watch.Elapsed.TotalSeconds);
            watch.Reset();

            sourceDfsu.Close();
            targetDfsu.Close();
        }
示例#6
0
        /// <summary>
        /// Create a difference file between <paramref name="referenceFilename"/>
        /// and <paramref name="compareFilename"/>, and store it in
        /// <paramref name="diffFilename"/>.
        /// The compare-file data is interpolated to the reference-file mesh, if
        /// meshes does not match.
        /// </summary>
        /// <param name="referenceFilename">Reference data for comparison</param>
        /// <param name="compareFilename">Comparison data</param>
        /// <param name="diffFilename">File to store difference data to</param>
        /// <param name="deleteValueDiff">If set to true, comparing delete value to non-delete value will return the non-delete value</param>
        public static void DfsuDiff(string referenceFilename, string compareFilename, string diffFilename, bool deleteValueDiff = true)
        {
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            // Open reference file and comparison file
            DfsuFile refdfsu = DfsFileFactory.DfsuFileOpen(referenceFilename);
            DfsuFile comdfsu = DfsFileFactory.DfsuFileOpen(compareFilename);

            float refDeleteValueFloat = refdfsu.DeleteValueFloat;
            float comDeleteValueFloat = comdfsu.DeleteValueFloat;

            // Create diff file, matching reference file.
            DfsuBuilder builder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);

            // Setup header and geometry, copy from source file
            builder.SetNodes(refdfsu.X, refdfsu.Y, refdfsu.Z, refdfsu.Code);
            builder.SetElements(refdfsu.ElementTable);
            builder.SetProjection(refdfsu.Projection);
            builder.SetZUnit(refdfsu.ZUnit);
            builder.SetTimeInfo(refdfsu.StartDateTime, refdfsu.TimeStepInSeconds);

            // Add dynamic items, copying from source
            foreach (IDfsSimpleDynamicItemInfo itemInfo in refdfsu.ItemInfo)
            {
                builder.AddDynamicItem(itemInfo.Name, itemInfo.Quantity);
            }

            DfsuFile diffDfsu = builder.CreateFile(diffFilename);

            watch.Stop();
            Console.Out.WriteLine("Create File : " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();

            // Build up mesh structures for interpolation
            SMeshData refMesh = SCreate(refdfsu);
            SMeshData comMesh = SCreate(comdfsu);

            watch.Stop();
            Console.Out.WriteLine("Create mesh  : " + watch.Elapsed.TotalSeconds);
            watch.Reset();

            watch.Start();
            bool meshEquals = refMesh.EqualsGeometry(comMesh);

            if (!meshEquals)
            {
                comMesh.BuildDerivedData();
            }
            watch.Stop();
            Console.Out.WriteLine("Build Deriv : " + watch.Elapsed.TotalSeconds);
            watch.Reset();

            MeshInterpolator2D interpolator = null;

            float[] targetData = null;

            // Do not interpolate if meshes equals
            if (!meshEquals)
            {
                watch.Start();
                // Build up interpolatin structures
                interpolator = new MeshInterpolator2D(comMesh, MeshValueType.Elements)
                {
                    DeleteValue      = comdfsu.DeleteValueFloat,
                    DeleteValueFloat = comdfsu.DeleteValueFloat,
                    //AllowExtrapolation = true,
                };
                interpolator.SetTarget(refMesh, MeshValueType.Elements);
                // Temporary, interpolated compare-data
                targetData = new float[diffDfsu.NumberOfElements];
                watch.Stop();
                Console.Out.WriteLine("Interpolator: " + watch.Elapsed.TotalSeconds);
                watch.Reset();
            }

            watch.Start();

            // Loop over all time steps
            IDfsItemData <float> refData;
            IDfsItemData <float> comData;

            while (null != (refData = refdfsu.ReadItemTimeStepNext() as IDfsItemData <float>) &&
                   null != (comData = comdfsu.ReadItemTimeStepNext() as IDfsItemData <float>))
            {
                if (interpolator != null)
                {
                    interpolator.InterpolateElmtToTarget(comData.Data, targetData);
                }
                else
                {
                    targetData = comData.Data;
                }

                for (int i = 0; i < targetData.Length; i++)
                {
                    // ReSharper disable CompareOfFloatsByEqualityOperator
                    if (refData.Data[i] != refDeleteValueFloat &&
                        targetData[i] != comDeleteValueFloat)
                    {
                        targetData[i] = refData.Data[i] - targetData[i];
                    }

                    else if (refData.Data[i] == refDeleteValueFloat &&
                             targetData[i] == comDeleteValueFloat)
                    {
                        targetData[i] = refDeleteValueFloat;
                    }

                    else if (deleteValueDiff)
                    {
                        if (refData.Data[i] != refDeleteValueFloat)
                        {
                            targetData[i] = refData.Data[i];
                        }
                        else // (targetData[i] != comDeleteValueFloat)
                        {
                            targetData[i] = -targetData[i];
                        }
                    }
                    else
                    {
                        targetData[i] = refDeleteValueFloat;
                    }
                    // ReSharper restore CompareOfFloatsByEqualityOperator
                }

                diffDfsu.WriteItemTimeStepNext(refData.Time, targetData);
            }
            watch.Stop();
            Console.Out.WriteLine("Interpolate : " + watch.Elapsed.TotalSeconds);
            watch.Reset();

            refdfsu.Close();
            comdfsu.Close();
            diffDfsu.Close();
        }
示例#7
0
        /// <summary>
        /// Create a difference file between <paramref name="referenceFilename"/>
        /// and <paramref name="compareFilename"/>, and store it in
        /// <paramref name="diffFilename"/>.
        /// The compare-file data is interpolated to the reference-file mesh, if
        /// meshes does not match.
        /// </summary>
        /// <param name="referenceFilename">Reference data for comparison</param>
        /// <param name="compareFilename">Comparison data</param>
        /// <param name="diffFilename">File to store difference data to</param>
        public static void DfsuDiff(string referenceFilename, string compareFilename, string diffFilename)
        {
            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            // Open reference file and comparison file
            DfsuFile refdfsu = DfsFileFactory.DfsuFileOpen(referenceFilename);
            DfsuFile comdfsu = DfsFileFactory.DfsuFileOpen(compareFilename);

            float deleteValueFloat = refdfsu.DeleteValueFloat;

            // Create diff file, matching reference file.
            DfsuBuilder builder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);

            // Setup header and geometry, copy from source file
            builder.SetNodes(refdfsu.X, refdfsu.Y, refdfsu.Z, refdfsu.Code);
            builder.SetElements(refdfsu.ElementTable);
            builder.SetProjection(refdfsu.Projection);
            builder.SetZUnit(refdfsu.ZUnit);
            builder.SetTimeInfo(refdfsu.StartDateTime, refdfsu.TimeStepInSeconds);

            // Add dynamic items, copying from source
            foreach (DfsuDynamicItemInfo itemInfo in refdfsu.ItemInfo)
            {
                builder.AddDynamicItem(itemInfo.Name, itemInfo.Quantity);
            }

            DfsuFile diffDfsu = builder.CreateFile(diffFilename);

            watch.Stop();
            Console.Out.WriteLine("Create File : " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();

            // Build up mesh structures for interpolation
            MeshData sourceMesh = Create(refdfsu);
            MeshData targetMesh = Create(diffDfsu);

            sourceMesh.BuildDerivedData();

            watch.Stop();
            Console.Out.WriteLine("Build mesh  : " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();

            // Build up interpolatin structures
            MeshInterpolator2D interpolator = new MeshInterpolator2D(sourceMesh)
            {
                DeleteValue      = refdfsu.DeleteValueFloat,
                DeleteValueFloat = refdfsu.DeleteValueFloat,
            };

            interpolator.SetTarget(targetMesh);

            watch.Stop();
            Console.Out.WriteLine("Interpolator: " + watch.Elapsed.TotalSeconds);
            watch.Reset();
            watch.Start();

            // Temporary, interpolated compare-data
            float[] targetData = new float[diffDfsu.NumberOfElements];

            // Loop over all time steps
            IDfsItemData <float> refData;
            IDfsItemData <float> comData;

            while (null != (refData = refdfsu.ReadItemTimeStepNext() as IDfsItemData <float>) &&
                   null != (comData = comdfsu.ReadItemTimeStepNext() as IDfsItemData <float>))
            {
                interpolator.InterpolateToTarget(comData.Data, targetData);

                for (int i = 0; i < targetData.Length; i++)
                {
                    if (refData.Data[i] != deleteValueFloat &&
                        targetData[i] != deleteValueFloat)
                    {
                        targetData[i] = refData.Data[i] - targetData[i];
                    }
                    else
                    {
                        targetData[i] = deleteValueFloat;
                    }
                }
                diffDfsu.WriteItemTimeStepNext(refData.Time, targetData);
            }
            watch.Stop();
            Console.Out.WriteLine("Interpolate : " + watch.Elapsed.TotalSeconds);
            watch.Reset();

            refdfsu.Close();
            comdfsu.Close();
            diffDfsu.Close();
        }
示例#8
0
        /// <summary>
        /// Example of plotting dfsu file data, water levels with a velocity vector overlay.
        /// </summary>
        public static void DfsuTest(bool makeBmp)
        {
            DHI.Chart.Map.Chart.Init();

            // File to load
            string   pathName = Path.Combine(UnitTestHelper.TestDataRoot, @"OresundHD.dfsu");
            DfsuFile dfsu     = DfsFileFactory.DfsuFileOpen(pathName);

            // FemVolGridData is data for the water levels, a value in the center of each element, used for coloring
            FemVolGridData data = new FemVolGridData();

            data.CreateNodesAndElements(dfsu.NumberOfNodes, dfsu.NumberOfElements, dfsu.X, dfsu.Y, dfsu.Z, dfsu.ElementTable);

            // FemVolVectorData is data for the vector overlay
            FemVolVectorData uvData = new FemVolVectorData();

            uvData.CreateNodesAndElements(dfsu.NumberOfNodes, dfsu.NumberOfElements, dfsu.X, dfsu.Y, dfsu.Z, dfsu.ElementTable);
            uvData.CreateUV();
            uvData.CreateStructuredElements(50, 100);

            // Create chart
            DHI.Chart.Map.Chart chart = new DHI.Chart.Map.Chart(1024, 1024);

            // Add overlay that plots the water levels
            FemVolGridOverlay overlay = new FemVolGridOverlay();

            overlay.SetGridData(data);
            overlay.EnableNiceValue = true;
            overlay.CreateAutoScaledRainbowPalette();
            overlay.EnableIsoline = true;
            overlay.ColoringType  = MapOverlay.EColoringType.ContinuousColoring;
            overlay.SetFeathering(true, 0.5f);
            overlay.EnableIsolineLabel = true;
            overlay.SetLineColor(MapOverlay.ELineType.Isoline, Color.LawnGreen);
            //overlay.DrawElementNumbers = true;
            chart.AddOverlay(overlay);

            // Add overlay that plots the vectors
            FemVolVectorOverlay uvOverlay = new FemVolVectorOverlay();

            uvOverlay.SetVectorData(uvData);
            uvOverlay.SetScale(VectorOverlay.EScaleType.UserDefinedScale, 2000.0);
            uvOverlay.EnableAutomaticScaling = false;
            uvOverlay.VectorStyle            = FemVolVectorOverlay.EVectorStyle.StructuredVectors;
            uvOverlay.LineColor = Color.BlueViolet;
            uvOverlay.SetLineThickness(VectorOverlay.EVectorType.NormalVector, 0.4f);
            chart.AddOverlay(uvOverlay);

            // 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);

            string pngFilepath = null;

            // Loop over the first 4 time steps
            for (int i = 0; i < 4; i++)
            {
                // Set water level data
                data.SetElementValues(dfsu.ReadItemTimeStep(1, i).Data as float[]);
                // Set u-v vector data
                uvData.SetUV(dfsu.ReadItemTimeStep(2, i).Data as float[], dfsu.ReadItemTimeStep(3, i).Data as float[]);
                // When running with autoscaled palette, an update is required.
                overlay.UpdatePalette();
                // Draw to bitmap
                Bitmap bmp = chart.DrawBitmap();

                // Save bitmap to disc
                if (makeBmp)
                {
                    pngFilepath = Path.Combine(UnitTestHelper.TestDataRoot, string.Format(@"test_oresundHD.1.{0}.png", i));
                    bmp.Save(pngFilepath);
                }
            }

            chart.Dispose();

            if (makeBmp && pngFilepath != null) // Show last bitmap saved
            {
                System.Diagnostics.Process.Start(pngFilepath);
            }
        }
示例#9
0
        /// <summary>
        /// Extract sub-area of dfsu (2D) file to a new dfsu file
        /// </summary>
        /// <param name="sourceFilename">Name of source file, i.e. OresundHD.dfsu test file</param>
        /// <param name="outputFilename">Name of output file</param>
        /// <param name="x1">Lower left x coordinate of sub area</param>
        /// <param name="y1">Lower left y coordinate of sub area</param>
        /// <param name="x2">upper right x coordinate of sub area</param>
        /// <param name="y2">upper right y coordinate of sub area</param>
        public static void ExtractSubareaDfsu2D(string sourceFilename, string outputFilename, double x1, double y1, double x2, double y2)
        {
            DfsuFile dfsu = DfsFileFactory.DfsuFileOpen(sourceFilename);

            // Node coordinates
            double[] X    = dfsu.X;
            double[] Y    = dfsu.Y;
            float[]  Z    = dfsu.Z;
            int[]    Code = dfsu.Code;

            // Loop over all elements, and all its nodes: If one node is inside
            // region, element (and nodes) are to be included in new mesh
            List <int> elmtsIncluded = new List <int>();

            bool[] nodesIncluded = new bool[dfsu.NumberOfNodes];
            for (int i = 0; i < dfsu.NumberOfElements; i++)
            {
                // Nodes of element
                int[] nodes = dfsu.ElementTable[i];

                // Check if one of the nodes of the element is inside region
                bool elmtIncluded = false;
                for (int j = 0; j < nodes.Length; j++)
                {
                    int node = nodes[j] - 1;
                    if (x1 <= X[node] && X[node] <= x2 && y1 <= Y[node] && Y[node] <= y2)
                    {
                        elmtIncluded = true;
                    }
                }

                if (elmtIncluded)
                {
                    // Add element to list of included elements
                    elmtsIncluded.Add(i);
                    // Mark all nodes of element as included
                    for (int j = 0; j < nodes.Length; j++)
                    {
                        int node = nodes[j] - 1;
                        nodesIncluded[node] = true;
                    }
                }
            }

            // array containing numbers of existing nodes in new mesh (indices)
            int[] renumber = new int[dfsu.NumberOfNodes];

            // new mesh nodes
            List <double> X2      = new List <double>();
            List <double> Y2      = new List <double>();
            List <float>  Z2      = new List <float>();
            List <int>    Code2   = new List <int>();
            List <int>    nodeIds = new List <int>();

            int i2 = 0;

            for (int i = 0; i < dfsu.NumberOfNodes; i++)
            {
                if (nodesIncluded[i])
                {
                    X2.Add(X[i]);
                    Y2.Add(Y[i]);
                    Z2.Add(Z[i]);
                    Code2.Add(Code[i]);
                    nodeIds.Add(dfsu.NodeIds[i]);
                    // Node with index i will get index i2 in new mesh
                    renumber[i] = i2;
                    i2++;
                }
            }

            // New mesh elements
            List <int[]> elmttable2 = new List <int[]>();
            List <int>   elmtIds    = new List <int>();

            for (int i = 0; i < elmtsIncluded.Count; i++)
            {
                // Add new element
                int   elmt  = elmtsIncluded[i];
                int[] nodes = dfsu.ElementTable[elmt];
                // newNodes must be renumbered
                int[] newNodes = new int[nodes.Length];
                for (int j = 0; j < nodes.Length; j++)
                {
                    // Do the renumbering of nodes from existing mesh to new mesh
                    newNodes[j] = renumber[nodes[j] - 1] + 1;
                }
                elmttable2.Add(newNodes);
                elmtIds.Add(dfsu.ElementIds[i]);
            }

            // Create 2D dfsu file
            DfsuBuilder builder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);

            // Setup header and geometry
            builder.SetNodes(X2.ToArray(), Y2.ToArray(), Z2.ToArray(), Code2.ToArray());
            //builder.SetNodeIds(nodeIds.ToArray());
            builder.SetElements(elmttable2.ToArray());
            builder.SetElementIds(elmtIds.ToArray()); // retain original element id's
            builder.SetProjection(dfsu.Projection);
            builder.SetTimeInfo(dfsu.StartDateTime, dfsu.TimeStepInSeconds);
            if (dfsu.ZUnit == eumUnit.eumUUnitUndefined)
            {
                builder.SetZUnit(eumUnit.eumUmeter);
            }
            else
            {
                builder.SetZUnit(dfsu.ZUnit);
            }

            // Add dynamic items, copying from source
            for (int i = 0; i < dfsu.ItemInfo.Count; i++)
            {
                IDfsSimpleDynamicItemInfo itemInfo = dfsu.ItemInfo[i];
                builder.AddDynamicItem(itemInfo.Name, itemInfo.Quantity);
            }

            // Create new file
            DfsuFile dfsuOut = builder.CreateFile(outputFilename);

            // Add new data
            float[] data2 = new float[elmtsIncluded.Count];
            for (int i = 0; i < dfsu.NumberOfTimeSteps; i++)
            {
                for (int j = 0; j < dfsu.ItemInfo.Count; j++)
                {
                    // Read data from existing dfsu
                    IDfsItemData <float> itemData = (IDfsItemData <float>)dfsu.ReadItemTimeStep(j + 1, i);
                    // Extract value for elements in new mesh
                    for (int k = 0; k < elmtsIncluded.Count; k++)
                    {
                        data2[k] = itemData.Data[elmtsIncluded[k]];
                    }
                    // write data
                    dfsuOut.WriteItemTimeStepNext(itemData.Time, data2);
                }
            }
            dfsuOut.Close();
            dfsu.Close();
        }
示例#10
0
        /// <summary>
        /// Extract a single layer from a 3D dfsu file, and write it to a 2D dfsu file.
        /// <para>
        /// If a layer value does not exist for a certain 2D element, delete value is written
        /// to the 2D resut file. This is relevant for Sigma-Z type of files.
        /// </para>
        /// </summary>
        /// <param name="filenameDfsu3">Name of 3D dfsu source file</param>
        /// <param name="filenameDfsu2">Name of 2D dfsu result file</param>
        /// <param name="layerNumber">Layer to extract.
        ///   <para>
        ///     Positive values count from bottom up i.e. 1 is bottom layer, 2 is second layer from bottom etc.
        ///   </para>
        ///   <para>
        ///     Negative values count from top down, i.e. -1 is toplayer, -2 is second layer from top etc.
        ///   </para>
        /// </param>
        public static void ExtractDfsu2DLayerFrom3D(string filenameDfsu3, string filenameDfsu2, int layerNumber)
        {
            IDfsuFile dfsu3File = DfsFileFactory.DfsuFileOpen(filenameDfsu3);

            // Check that dfsu3 file is a 3D dfsu file.
            switch (dfsu3File.DfsuFileType)
            {
            case DfsuFileType.Dfsu2D:
            case DfsuFileType.DfsuVerticalColumn:
            case DfsuFileType.DfsuVerticalProfileSigma:
            case DfsuFileType.DfsuVerticalProfileSigmaZ:
                throw new InvalidOperationException("Input file is not a 3D dfsu file");
            }

            // Calculate offset from toplayer element. Offset is between 0 (top layer) and
            // dfsu3File.NumberOfLayers-1 (bottom layer)
            int topLayerOffset;

            if (layerNumber > 0 && layerNumber <= dfsu3File.NumberOfLayers)
            {
                topLayerOffset = dfsu3File.NumberOfLayers - layerNumber;
            }
            else if (layerNumber < 0 && -layerNumber <= dfsu3File.NumberOfLayers)
            {
                topLayerOffset = -layerNumber - 1;
            }
            else
            {
                throw new ArgumentException("Layer number is out of range");
            }

            double[] xv = dfsu3File.X;
            double[] yv = dfsu3File.Y;
            float[]  zv = dfsu3File.Z;
            int[]    cv = dfsu3File.Code;

            // --------------------------------------------------
            // Create 2D mesh from 3D mesh

            // List of new 2D nodes
            int           node2DCount = 0;
            List <double> xv2         = new List <double>();
            List <double> yv2         = new List <double>();
            List <float>  zv2         = new List <float>();
            List <int>    cv2         = new List <int>();

            // Renumbering array, from 3D node numbers to 2D node numbers
            // i.e. if a 3D element refers to node number k, the 2D element node number is renumber[k]
            int[] renumber = new int[dfsu3File.NumberOfNodes];

            // Coordinates of last created node
            double xr2 = -1e-10;
            double yr2 = -1e-10;

            // Create 2D nodes, by skipping nodes with equal x,y coordinates
            for (int i = 0; i < dfsu3File.NumberOfNodes; i++)
            {
                // If 3D x,y coordinates are equal to the last created 2D node,
                // map this node to the last created 2D node, otherwise
                // create new 2D node and map to that one
                if (xv[i] != xr2 || yv[i] != yr2)
                {
                    // Create new node
                    node2DCount++;
                    xr2 = xv[i];
                    yr2 = yv[i];
                    float zr2 = zv[i];
                    int   cr2 = cv[i];
                    xv2.Add(xr2);
                    yv2.Add(yr2);
                    zv2.Add(zr2);
                    cv2.Add(cr2);
                }
                // Map this 3D node to the last created 2D node.
                renumber[i] = node2DCount;
            }

            // Find indices of top layer elements
            IList <int> topLayer = dfsu3File.FindTopLayerElements();

            // Create element table for 2D dfsu file
            int[][] elmttable2 = new int[topLayer.Count][];
            for (int i = 0; i < topLayer.Count; i++)
            {
                // 3D element nodes
                int[] elmt3 = dfsu3File.ElementTable[topLayer[i]];
                // 2D element nodes, only half as big, so copy over the first half
                int[] elmt2 = new int[elmt3.Length / 2];
                for (int j = 0; j < elmt2.Length; j++)
                {
                    elmt2[j] = renumber[elmt3[j]];
                }
                elmttable2[i] = elmt2;
            }

            // --------------------------------------------------
            // Create 2D dfsu file
            DfsuBuilder builder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);

            // Setup header and geometry
            builder.SetNodes(xv2.ToArray(), yv2.ToArray(), zv2.ToArray(), cv2.ToArray());
            builder.SetElements(elmttable2);
            builder.SetProjection(dfsu3File.Projection);
            builder.SetTimeInfo(dfsu3File.StartDateTime, dfsu3File.TimeStepInSeconds);
            if (dfsu3File.ZUnit == eumUnit.eumUUnitUndefined)
            {
                builder.SetZUnit(eumUnit.eumUmeter);
            }
            else
            {
                builder.SetZUnit(dfsu3File.ZUnit);
            }

            // Add dynamic items, copying from source, though not the first one, if it
            // contains the z-variation on the nodes
            for (int i = 0; i < dfsu3File.ItemInfo.Count; i++)
            {
                IDfsSimpleDynamicItemInfo itemInfo = dfsu3File.ItemInfo[i];
                if (itemInfo.ElementCount == dfsu3File.NumberOfElements)
                {
                    builder.AddDynamicItem(itemInfo.Name, itemInfo.Quantity);
                }
            }

            // Create file
            DfsuFile dfsu2File = builder.CreateFile(filenameDfsu2);

            // --------------------------------------------------
            // Process data

            // Check if the layer number exists for 2D element, i.e. if that element
            // in 2D has that number of columnes in the 3D (relevant for sigma-z files)
            // If elementExists[i] is false, write delete value to file
            bool[] elementExists     = new bool[topLayer.Count];
            int    numLayersInColumn = topLayer[0] + 1;

            elementExists[0] = (numLayersInColumn - topLayerOffset) > 0;
            for (int i = 1; i < topLayer.Count; i++)
            {
                numLayersInColumn = (topLayer[i] - topLayer[i - 1]);
                elementExists[i]  = (numLayersInColumn - topLayerOffset) > 0;
            }

            // For performance, use predefined itemdata objects when reading data from dfsu 3D file
            IDfsItemData <float>[] dfsu3ItemDatas = new IDfsItemData <float> [dfsu3File.ItemInfo.Count];
            for (int j = 0; j < dfsu3File.ItemInfo.Count; j++)
            {
                dfsu3ItemDatas[j] = (IDfsItemData <float>)dfsu3File.ItemInfo[j].CreateEmptyItemData();
            }

            // Float data to write to dfsu 2D file
            float[] data2            = new float[dfsu2File.NumberOfElements];
            float   deleteValueFloat = dfsu2File.DeleteValueFloat;

            for (int i = 0; i < dfsu3File.NumberOfTimeSteps; i++)
            {
                for (int j = 0; j < dfsu3File.ItemInfo.Count; j++)
                {
                    // Read data from 3D dfsu
                    IDfsItemData <float> data3Item = dfsu3ItemDatas[j];
                    bool ok = dfsu3File.ReadItemTimeStep(data3Item, i);
                    // 3D data
                    float[] data3 = data3Item.Data;

                    // Skip any items not having size = NumberOfElments (the z-variation on the nodes)
                    if (data3.Length != dfsu3File.NumberOfElements)
                    {
                        continue;
                    }

                    // Loop over all 2D elements
                    for (int k = 0; k < topLayer.Count; k++)
                    {
                        // Extract layer data from 3D column into 2D element value
                        if (elementExists[k])
                        {
                            data2[k] = data3[topLayer[k] - topLayerOffset];
                        }
                        else
                        {
                            data2[k] = deleteValueFloat;
                        }
                    }

                    dfsu2File.WriteItemTimeStepNext(data3Item.Time, data2);
                }
            }

            dfsu3File.Close();
            dfsu2File.Close();
        }