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