Ejemplo n.º 1
0
        /// <summary>
        /// Introductory example of how to load a dfsu file.
        /// <para>
        /// The method assumes that the OresundHD.dfsu test file
        /// is the input file.
        /// </para>
        /// </summary>
        /// <param name="filename">path and name of OresundHD.dfsu test file</param>
        public static void ReadingDfsuFile(string filename)
        {
            IDfsuFile file = DfsuFile.Open(filename);

            // Read geometry
            int    numberOfElements     = file.NumberOfElements; // 3636
            int    numberOfNodes        = file.NumberOfNodes;    // 2057
            double firstNodeXCoordinate = file.X[0];             // 359978.8

            int[] firstElementNodes = file.ElementTable[0];      // [1, 2, 3]

            // Read dynamic item info
            string      firstItemName = file.ItemInfo[0].Name;     // "Surface elevation"
            eumQuantity quantity      = file.ItemInfo[0].Quantity; // eumISurfaceElevation in eumUmeter

            // load data for the first item, 6th timestep
            float[] itemTimeStepData = (float[])file.ReadItemTimeStep(1, 5).Data;
            // Read the value of the third element
            float thirdElementValue = itemTimeStepData[2]; // 0.0014070312

            file.Close();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Example of how to create a Dfsu file from scratch. This method
        /// creates a copy of the OresundHD.dfsu test file.
        /// <para>
        /// Data for static and dynamic item is taken from a source dfs file,
        /// which here is the OresundHD.dfsu test file. The data could come
        /// from any other source.
        /// </para>
        /// </summary>
        /// <param name="sourceFilename">Path and name of the OresundHD.dfsu test file</param>
        /// <param name="filename">Path and name of the new file to create</param>
        /// <param name="zInMeters">Flag specifying whether the z values are in meters or feet </param>
        public static void CreateDfsuFile(string sourceFilename, string filename, bool zInMeters)
        {
            IDfsuFile source = DfsuFile.Open(sourceFilename);

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

            // Setup header and geometry, copy from source file
            builder.SetNodes(source.X, source.Y, source.Z, source.Code);
            builder.SetElements(source.ElementTable);
            builder.SetProjection(source.Projection);
            builder.SetTimeInfo(source.StartDateTime, source.TimeStepInSeconds);
            if (zInMeters)
            {
                builder.SetZUnit(eumUnit.eumUmeter);
            }
            else
            {
                builder.SetZUnit(eumUnit.eumUfeet);
            }

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

            DfsuFile file = builder.CreateFile(filename);

            // Add data for all item-timesteps, copying from source
            IDfsItemData sourceData;

            while (null != (sourceData = source.ReadItemTimeStepNext()))
            {
                file.WriteItemTimeStepNext(sourceData.Time, sourceData.Data);
            }

            source.Close();
            file.Close();
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Example of how to modify the geometry of a dfsu file.
        /// The method will rotate the geometry by 125 degrees.
        /// <para>
        /// The method will work on any dfsu file. The OresundHD.dfsu test file
        /// (preferably a copy of it) can be used as input file.
        /// </para>
        /// </summary>
        /// <param name="filename">Path and name of a dfsu file</param>
        public static void ModifyDfsuFileGeometry(string filename)
        {
            // Open file for editing
            IDfsuFile dfsuFile = DfsuFile.OpenEdit(filename);

            dfsuFile.TimeStepInSeconds /= 2;
            dfsuFile.StartDateTime      = new DateTime(2019, 6, 27, 13, 50, 30);

            // Make a rotation matrix
            double rotation = 125.0 / 180.0 * System.Math.PI;
            double x1       = System.Math.Cos(rotation);
            double y1       = -System.Math.Sin(rotation);
            double x2       = System.Math.Sin(rotation);
            double y2       = System.Math.Cos(rotation);

            // Get the x- and y-coordinates from the file
            double[] x = dfsuFile.X;
            double[] y = dfsuFile.Y;

            // Point to rotate around
            double x0 = x[0];
            double y0 = y[0];

            // Rotate coordinates
            for (int i = 0; i < dfsuFile.NumberOfNodes; i++)
            {
                double xx = x[i] - x0;
                double yy = y[i] - y0;
                x[i] = x1 * xx + y1 * yy + x0;
                y[i] = x2 * xx + y2 * yy + y0;
            }

            // Set the x- and y-coordinates back to the file
            dfsuFile.X = x;
            dfsuFile.Y = y;

            // Close the file
            dfsuFile.Close();
        }
        private void ComputeHmax(string filename)
        {
            btStart.Enabled = false;                        //Disable the Start button, to prevent user from running the tool twice at the same time
            btClose.Enabled = false;                        //Disable the Close button, to prevent user from closing the tool while running
            //Read input file and find relevant items
            IDfsuFile InputFile = DfsuFile.Open(filename);  //Open the file
            int       ItemNb    = InputFile.ItemInfo.Count; //Number of items in the file
            int       ItemNbH   = -1;                       //Stores the item number for water depth. Initialised with a temporary value.
            int       ItemNbU   = -1;                       //Stores the item number for U velocity. Initialised with a temporary value.
            int       ItemNbV   = -1;                       //Stores the item number for V velocity. Initialised with a temporary value.

            for (int i = 0; i < ItemNb; i++)                //Loop finding appropriate items H, U and V
            {
                if (InputFile.ItemInfo[i].Name == "Total water depth")
                {
                    ItemNbH = i;                                                    //Save the actual item number when Total water depth is found
                }
                if (InputFile.ItemInfo[i].Name == "U velocity")
                {
                    ItemNbU = i;                                             //Save the actual item number when U velocity is found
                }
                if (InputFile.ItemInfo[i].Name == "V velocity")
                {
                    ItemNbV = i;                                             //Save the actual item number when V velocity is found
                }
            }
            if (ItemNbH == -1 || ItemNbU == -1 || ItemNbV == -1)                                       //If one of the required item cannot be found
            {
                btClose.Enabled = true;                                                                //Enable the Close button again
                throw new Exception("The result file doesn't contain the necessary items H, U and V"); //Throw error message
            }
            else
            {
                //Create output file, with same nodes, elements, projection and time info as the input file, but with different output items
                DfsuBuilder OutputBuilder = DfsuBuilder.Create(DfsuFileType.Dfsu2D);
                OutputBuilder.SetNodes(InputFile.X, InputFile.Y, InputFile.Z, InputFile.Code);
                OutputBuilder.SetElements(InputFile.ElementTable);
                OutputBuilder.SetProjection(InputFile.Projection);
                OutputBuilder.SetTimeInfo(InputFile.StartDateTime, InputFile.TimeStepInSeconds);
                OutputBuilder.SetZUnit(InputFile.ZUnit);
                OutputBuilder.AddDynamicItem("Maximum water depth", InputFile.ItemInfo[ItemNbH].Quantity);                                            //Create item H
                OutputBuilder.AddDynamicItem("U velocity @ max. depth", InputFile.ItemInfo[ItemNbU].Quantity);                                        //Create item U
                OutputBuilder.AddDynamicItem("V velocity @ max. depth", InputFile.ItemInfo[ItemNbV].Quantity);                                        //Create item V
                OutputBuilder.AddDynamicItem("Current speed @ max. depth", InputFile.ItemInfo[ItemNbU].Quantity);                                     //Create item Speed
                OutputBuilder.AddDynamicItem("Current direction @ max. depth", eumQuantity.Create(eumItem.eumICurrentDirection, eumUnit.eumUradian)); //Create item Direction. Note: eumQuantity requires "using DHI.Generic.MikeZero"
                //Initialization of all output variables. Both source data and output data are intialized with data from first time step of the input file.
                float[] SourceDataH     = (float[])InputFile.ReadItemTimeStep(ItemNbH + 1, 0).Data;                                                   //ReadItemTimeStep is 1-based! That is, the first time step must be numbered 1, whereas the first time step in the file is numbered 0, hence the +1.
                float[] SourceDataU     = (float[])InputFile.ReadItemTimeStep(ItemNbU + 1, 0).Data;
                float[] SourceDataV     = (float[])InputFile.ReadItemTimeStep(ItemNbV + 1, 0).Data;
                float[] OutputDataH     = (float[])InputFile.ReadItemTimeStep(ItemNbH + 1, 0).Data;
                float[] OutputDataU     = (float[])InputFile.ReadItemTimeStep(ItemNbU + 1, 0).Data;
                float[] OutputDataV     = (float[])InputFile.ReadItemTimeStep(ItemNbV + 1, 0).Data;
                float[] OutputDataSpeed = (float[])InputFile.ReadItemTimeStep(ItemNbU + 1, 0).Data; //Initialise speed with values of U at time step 0
                float[] OutputDataDir   = (float[])InputFile.ReadItemTimeStep(ItemNbU + 1, 0).Data; //Initialise direction with values of U at time step 0
                for (int m = 0; m < InputFile.NumberOfElements; m++)                                //Change speed and direction at first time step based on U and V values, with a loop over each element
                {
                    OutputDataSpeed[m] = (float)Math.Sqrt(Math.Pow(SourceDataU[m], 2) + Math.Pow(SourceDataV[m], 2));
                    OutputDataDir[m]   = (float)Math.Atan2(SourceDataU[m], SourceDataV[m]);
                }
                //Define the properties of the progress bar
                progressBar1.Maximum = InputFile.NumberOfTimeSteps - 1;
                progressBar1.Step    = 1;
                //Loop over all time steps to get results for maxH (starting from 2nd time step)
                for (int j = 1; j < InputFile.NumberOfTimeSteps; j++)
                {
                    SourceDataH = (float[])InputFile.ReadItemTimeStep(ItemNbH + 1, j).Data; //Load the new time step H data into the SourceDataH array. ReadItemTimeStep is 1-based!
                    SourceDataU = (float[])InputFile.ReadItemTimeStep(ItemNbU + 1, j).Data; //Load the new time step U data into the SourceDataU array. ReadItemTimeStep is 1-based!
                    SourceDataV = (float[])InputFile.ReadItemTimeStep(ItemNbV + 1, j).Data; //Load the new time step V data into the SourceDataV array. ReadItemTimeStep is 1-based!
                    for (int k = 0; k < InputFile.NumberOfElements; k++)                    //Loop over all elements
                    {
                        if (SourceDataH[k] > OutputDataH[k])                                //If the water depth for the new time step is higher than the previous maximum depth, then store the corresponding U, V, speed and direction values
                        {
                            OutputDataH[k]     = SourceDataH[k];
                            OutputDataU[k]     = SourceDataU[k];
                            OutputDataV[k]     = SourceDataV[k];
                            OutputDataSpeed[k] = (float)Math.Sqrt(Math.Pow(SourceDataU[k], 2) + Math.Pow(SourceDataV[k], 2));
                            OutputDataDir[k]   = (float)Math.Atan2(SourceDataU[k], SourceDataV[k]);
                        }
                    }
                    progressBar1.PerformStep(); //Increment progress bar
                }
                // Write results
                string   folder      = Path.GetDirectoryName(txtPath.Text);
                string   FileRoot    = Path.GetFileNameWithoutExtension(txtPath.Text);
                string   FileNameOut = folder + "\\" + FileRoot + "_Statistics_Hmax.dfsu"; //Add suffix to input file name, to be used for output file
                DfsuFile OutputFile  = OutputBuilder.CreateFile(FileNameOut);              //Create output file
                OutputFile.WriteItemTimeStepNext(0, OutputDataH);                          //Write H data. Time set to 0 : ignored since equidistant interval
                OutputFile.WriteItemTimeStepNext(0, OutputDataU);                          //Write U data
                OutputFile.WriteItemTimeStepNext(0, OutputDataV);                          //Write V data
                OutputFile.WriteItemTimeStepNext(0, OutputDataSpeed);                      //Write speed data
                OutputFile.WriteItemTimeStepNext(0, OutputDataDir);                        //Write direction data
                InputFile.Close();                                                         //Release the input file
                OutputFile.Close();                                                        //Release the output file
                MessageBox.Show("File created");                                           //Confirm that the file has been created
                progressBar1.Value = 0;                                                    //Reset the progress bar
                btStart.Enabled    = true;                                                 //Enable the Start button again
                btClose.Enabled    = true;                                                 //Enable the Close button again
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Find element (index) for a specified coordinate
        /// <para>
        /// The method assumes that the OresundHD.dfsu test file
        /// is the input file.
        /// </para>
        /// </summary>
        /// <param name="filename">path and name of OresundHD.dfsu test file</param>
        public static void FindElementForCoordinate(string filename)
        {
            IDfsuFile file = DfsuFile.Open(filename);

            double[] X = file.X;
            double[] Y = file.Y;

            // Coordinate to search for
            double xc = 346381;
            double yc = 6153637;

            // Loop over all elements - linear search, which may be slow!
            // If to find element for a large number of coordinates and if especially the
            // file has many elements, then a search tree procedure should be used to
            // optimize the searching performance.
            int elmt = -1; // result of search

            for (int i = 0; i < file.NumberOfElements; i++)
            {
                // Take out nodes for element
                int[] nodes = file.ElementTable[i];

                // Loop over all faces in element. The coordinate (x,y) is
                // inside an element if the coordinate is "left of" all faces,
                // when travelling faces counter-clockwise

                bool isInside = true;
                for (int j = 0; j < nodes.Length; j++)
                {
                    // face start/end node indices
                    int a = nodes[j] - 1;
                    int b = nodes[(j + 1) % nodes.Length] - 1;

                    // Assuming face is A->B and coordinate is C, then "left of" test:
                    // (B-A) X (C-A) > 0
                    // where X is the cross product
                    double cross = (X[b] - X[a]) * (yc - Y[a]) - (Y[b] - Y[a]) * (xc - X[a]);
                    if (cross < 0)
                    {
                        // (xc, yc) is "right of", hence not inside, skip to next element
                        isInside = false;
                        break;
                    }
                }
                if (isInside)
                {
                    // All "left of" tests succeded, element found!
                    elmt = i;
                    break;
                }
            }

            if (elmt >= 0)
            {
                Console.Out.WriteLine("Found     element index: = {0}", elmt);
                Console.Out.WriteLine("(xc,yc) = ({0},{1})", xc, yc);
                int[] resNodes = file.ElementTable[elmt];
                for (int j = 0; j < resNodes.Length; j++)
                {
                    int node = resNodes[j] - 1;
                    Console.Out.WriteLine("(x,y)   = ({0},{1})", X[node], Y[node]);
                }
            }

            file.Close();
        }
Ejemplo n.º 6
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();
        }