@@ -9,43 +9,43 @@ def CheckForNull(obj):
99
1010class DfsuFileType (IntEnum ):
1111
12+ # 1D series
13+ Dfsu1D = 1 ,
14+
1215 # 2D area series
13- Dfsu2D = 1 ,
16+ Dfsu2D = 2 ,
1417
1518 # 1D vertical column
16- DfsuVerticalColumn = 2 ,
19+ DfsuVerticalColumn = 3 ,
1720
1821 # 2D vertical slice through a Dfsu3DSigma
19- DfsuVerticalProfileSigma = 3 ,
22+ DfsuVerticalProfileSigma = 4 ,
2023
2124 # 2D vertical slice through a Dfsu3DSigmaZ
22- DfsuVerticalProfileSigmaZ = 4 ,
25+ DfsuVerticalProfileSigmaZ = 5 ,
2326
2427 # 3D file with sigma coordinates, i.e., a constant number of layers.
25- Dfsu3DSigma = 5 ,
28+ Dfsu3DSigma = 6 ,
2629
2730 # 3D file with sigma and Z coordinates, i.e. a varying number of layers.
28- Dfsu3DSigmaZ = 6 ,
31+ Dfsu3DSigmaZ = 7 ,
2932
3033 # 0D point series of spectral data (frequency, direction)
31- DfsuSpectral0D = 7
34+ DfsuSpectral0D = 8
35+
36+ # 1D line series of spectral data (node, frequency, direction)
37+ DfsuSpectral1D = 9
38+
39+ # 2D area series of spectral data (elmt, frequency, direction)
40+ DfsuSpectral2D = 10
3241
33- # 1D line series of spectral data (nodes, frequency, direction)
34- DfsuSpectral1D = 8
3542
36- # 2D area series of spectral data (elements, frequency, direction)
37- DfsuSpectral2D = 9
38-
3943class DfsuFile (object ):
4044 """
4145 Class for exposing data from a dfsu file.
42-
4346 Use the DfsFileFactory to open an existing dfsu file.
44-
4547 Use the DfsuBuilder to create a new dfsu file.
46-
4748 You can read, write and append item-timesteps to the file.
48-
4949 The geometry can be altered, by moving the nodes, but the element connectivity can not be changed.
5050 """
5151
@@ -55,6 +55,8 @@ def __init__(self, dfsFile = None):
5555 self .DfsuFileType = DfsuFileType .Dfsu2D ;
5656 self .NumberOfLayers = - 1 ;
5757 self .NumberOfSigmaLayers = - 1 ;
58+ self .NumberOfFrequencies = - 1 ;
59+ self .NumberOfDirections = - 1 ;
5860
5961 # Static item
6062 self .__nodeIdItem = None ;
@@ -79,6 +81,10 @@ def __init__(self, dfsFile = None):
7981 self .ElementType = None ;
8082 self .ElementTable = [];
8183
84+ # Spectral definition
85+ self .Frequencies = None ;
86+ self .Directions = None ;
87+
8288 if (not dfsFile is None ):
8389 self .__Init (dfsFile )
8490
@@ -112,19 +118,35 @@ def __Init(self, dfsFile, build = False):
112118 else :
113119 self .NumberOfSigmaLayers = self .NumberOfLayers ;
114120
121+ if (self .FileInfo .DataType in (2002 , 2003 ) or (self .FileInfo .DataType == 2001 and (customBlock .Count == 6 ))):
122+ self .NumberOfFrequencies = customBlock [4 ];
123+ self .NumberOfDirections = customBlock [5 ];
124+ else :
125+ self .NumberOfFrequencies = 0 ;
126+ self .NumberOfDirections = 0 ;
127+
115128 # Figuring out dfsu file type from custom block MIKE_FM
116129 if (dimensions == 1 ):
117- self .DfsuFileType = DfsuFileType .DfsuVerticalColumn ;
130+ if (self .NumberOfLayers > 0 ):
131+ self .DfsuFileType = DfsuFileType .DfsuVerticalColumn ;
132+ elif (self .FileInfo .DataType == 2001 and self .IsSpectral ):
133+ # Spectral Frequency or Direction geometry
134+ self .DfsuFileType = DfsuFileType .DfsuSpectral1D ;
135+ else :
136+ self .DfsuFileType = DfsuFileType .Dfsu1D ;
137+
118138 elif (dimensions == 2 ):
119- if (self .NumberOfLayers == 0 ):
139+ if (self .FileInfo .DataType == 2001 and (self .NumberOfFrequencies * self .NumberOfDirections == numberOfElmts )):
140+ # Spectral Frequency-Direction (Rose-plot) geometry
141+ self .DfsuFileType = DfsuFileType .DfsuSpectral0D ;
142+ elif (self .NumberOfLayers == 0 ):
120143 self .DfsuFileType = DfsuFileType .Dfsu2D ;
121144 elif (self .NumberOfLayers == self .NumberOfSigmaLayers ):
122145 self .DfsuFileType = DfsuFileType .DfsuVerticalProfileSigma ;
123146 else :
124147 self .DfsuFileType = DfsuFileType .DfsuVerticalProfileSigmaZ ;
125-
126- elif (dimensions == 3 ):
127148
149+ elif (dimensions == 3 ):
128150 if (self .NumberOfLayers == self .NumberOfSigmaLayers ):
129151 self .DfsuFileType = DfsuFileType .Dfsu3DSigma ;
130152 else :
@@ -142,6 +164,9 @@ def __Init(self, dfsFile, build = False):
142164 # "Element type" , int
143165 # "No of nodes" , int
144166 # "Connectivity" , int
167+ # For spectral files also at least one of:
168+ # "Frequency" , double
169+ # "Direction" , double
145170
146171 self .__nodeIdItem = self .dfsFile .ReadStaticItemNext (); CheckForNull (self .__nodeIdItem );
147172 self .NodeIds = self .__nodeIdItem .Data
@@ -200,44 +225,19 @@ def __Init(self, dfsFile, build = False):
200225 k += 1
201226
202227 # Spectral Dfsu
203- frequency = self .dfsFile .ReadStaticItemNext ()
204- direction = self .dfsFile .ReadStaticItemNext ()
205- if self .FileInfo .DataType in (2002 , 2003 ) or ((frequency is not None ) and (direction is not None )):
206- self .Frequency = frequency .Data
207- self .Direction = direction .Data
208-
209- if (direction .Name != "Direction" ) or (frequency .Name != "Frequency" ):
210- raise Exception ("File is not a valid spectral dfsu file. It cannot be opened" )
211-
212- self .NumberOfFrequencies = len (self .Frequency ) #customBlock[4]
213- self .NumberOfDirections = len (self .Direction ) #customBlock[5]
214-
215- n2d = (self .NumberOfFrequencies + 1 )* (self .NumberOfDirections + 1 )
216- numberOfNodes = customBlock [0 ]
217- if (self .FileInfo .DataType == 2001 ):
218- if (dimensions == 2 ) and (n2d == numberOfNodes ):
219- # This is a point spectrum file
220- # the mesh is not a real geographical mesh, but an artificial one
221- # made for plotting in MIKE Zero
222- dimensions = 0
223- else :
224- raise Exception ("File is not a point spectrum dfsu file. It cannot be opened" )
225-
226- self .NumberOfLayers = 0
227- self .NumberOfSigmaLayers = 0
228-
229- if dimensions == 0 :
230- self .DfsuFileType = DfsuFileType .DfsuSpectral0D
231- elif dimensions == 1 :
232- self .DfsuFileType = DfsuFileType .DfsuSpectral1D
233- elif dimensions == 2 :
234- self .DfsuFileType = DfsuFileType .DfsuSpectral2D
228+ if (self .NumberOfFrequencies ):
229+ frequency = self .dfsFile .ReadStaticItemNext (); CheckForNull (frequency );
230+ self .Frequency = frequency .Data
231+ if (self .NumberOfDirections ):
232+ direction = self .dfsFile .ReadStaticItemNext (); CheckForNull (direction );
233+ self .Direction = direction .Data
235234
236235 self .NumberOfNodes = self .NodeIds .size ;
237236 self .ItemInfo = self .dfsFile .ItemInfo
238237
239238 self .NumberOfElements = self .ElementIds .size
240-
239+ #self.NumberOfNodes = self.X.size
240+
241241 if (not build ):
242242 # In append mode, move the file pointer to end of file
243243 # It was moved elsewhere when reading static data...
@@ -408,6 +408,9 @@ def __SetDeleteValueFloat(self, value):
408408 self .FileInfo .DeleteValueFloat = value
409409 DeleteValueFloat = property (__GetDeleteValueFloat , __SetDeleteValueFloat )
410410
411+ @property
412+ def IsSpectral (self ):
413+ return (self .NumberOfFrequencies > 0 ) or (self .NumberOfDirections > 0 )
411414
412415
413416 @staticmethod
@@ -480,20 +483,15 @@ def FindTopLayerElements(elementTable):
480483 """
481484 Find element indices (zero based) of the elements being the upper-most element
482485 in its column.
483-
484486 Each column is identified by matching node id numbers. For 3D elements the
485487 last half of the node numbers of the bottom element must match the first half
486488 of the node numbers in the top element. For 2D vertical elements the order of
487489 the node numbers in the bottom element (last half number of nodes) are reversed
488490 compared to those in the top element (first half number of nodes).
489-
490491 To find the number of elements in each column, assuming the result
491492 is stored in res:
492-
493493 For the first column it is res[0]+1.
494-
495494 For the i'th column, it is res[i]-res[i-1].
496-
497495 :returns: A list of element indices of top layer elements
498496 """
499497
@@ -546,17 +544,12 @@ def FindTopLayerElementsXY(elementTable, x, y):
546544 """
547545 Find element indices (zero based) of the elements being the upper-most element
548546 in its column.
549-
550547 This method uses the element center (x,y) coordinate, and identifies
551548 each column by having the same element center (x,y) coordinate.
552-
553549 To find the number of elements in each column, assuming the result
554550 is stored in res:
555-
556551 For the first column it is res[0]+1.
557-
558552 For the i'th column, it is res[i]-res[i-1].
559-
560553 :returns: A list of element indices of top layer elements
561554 """
562555
@@ -623,7 +616,6 @@ def FindMaxNumberOfLayers(topLayerElements):
623616 """
624617 Find the maximum number of layers, based on the indices of
625618 all top layer elements.
626-
627619 Assuming that the topLayerElements comes ordered.
628620 """
629621 # the first column has top-element-index + 1 layers
@@ -639,7 +631,6 @@ def FindMinNumberOfLayers(topLayerElements):
639631 """
640632 Find the minimum number of layers, based on the indices of
641633 all top layer elements.
642-
643634 Assuming that the <paramref name="topLayerElements"/> comes
644635 ordered.
645636 """
@@ -650,4 +641,3 @@ def FindMinNumberOfLayers(topLayerElements):
650641 if (layers < minLayers ):
651642 minLayers = layers ;
652643 return (minLayers );
653-
0 commit comments