1 """Data structures in Foam-Files that can't be directly represented by Python-Structures"""
2
3 from __future__ import division
4
5 from copy import deepcopy
6 import math
7 import re
8
9
10
11 from PyFoam.ThirdParty.six import integer_types,PY3,string_types
12
13 if PY3:
15 if a<b:
16 return -1
17 elif a==b:
18 return 0
19 else:
20 return 1
21
24 return "'"+str(self)+"'"
25
27 """Implementation to make __cmp__ work again in Python3
28
29 Implementing this method means that these objects are not hashable.
30 But that is OK
31 """
32 return self.__cmp__(other)==0
33
35 "Implementation to make __cmp__ work again in Python3"
36 return self.__cmp__(other)<0
37
40
43
46
49
50 -class Field(FoamDataType):
52 self.val=val
53 self.name=name
54 if type(val) in[list,UnparsedList,BinaryList]:
55 self.uniform=False
56 elif self.name==None:
57 self.uniform=True
58 else:
59 raise TypeError("Type",type(val),"of value",val,"can not be used to determine uniformity")
60
62 result=""
63 if self.uniform:
64 result+="uniform "
65 else:
66 result+="nonuniform "
67 if self.name:
68 result+=self.name+" "
69
70 result+=str(
71 PyFoam.Basics.FoamFileGenerator.FoamFileGenerator(
72 self.val,
73 longListThreshold=-1,
74 useFixedType=False
75 ))
76 return result
77
79 if other==None or type(other)!=Field:
80 return 1
81 if self.uniform!=other.uniform:
82 return cmp(self.uniform,other.uniform)
83 elif self.name!=other.name:
84 return cmp(self.name,other.name)
85 else:
86 return cmp(self.val,other.val)
87
89 assert(not self.uniform)
90 return self.val[key]
91
93 assert(not self.uniform)
94 self.val[key]=value
95
98
101
103 return "nonuniform "+self.name+" <BINARY DATA>"
104
107
112
115 assert(len(dims)==7)
116 self.dims=list(dims)
117
119 result="[ "
120 for v in self.dims:
121 result+=str(v)+" "
122 result+="]"
123 return result
124
126 if other==None:
127 return 1
128 return cmp(self.dims,other.dims)
129
131 return self.dims[key]
132
135
139
141 return "("+" ".join(["%g"%v for v in self.vals])+")"
142
144 if other==None or not issubclass(type(other),FixedLength):
145 return 1
146 return cmp(self.vals,other.vals)
147
149 return self.vals[key]
150
153
155 return len(self.vals)
156
160
162 x=self
163 if type(y)==Vector:
164 return Vector(x[0]+y[0],x[1]+y[1],x[2]+y[2])
165 elif type(y) in integer_types+(float,):
166 return Vector(x[0]+y,x[1]+y,x[2]+y)
167 else:
168 return NotImplemented
169
171 x=self
172 if type(y) in integer_types+(float,):
173 return Vector(x[0]+y,x[1]+y,x[2]+y)
174 else:
175 return NotImplemented
176
178 x=self
179 if type(y)==Vector:
180 return Vector(x[0]-y[0],x[1]-y[1],x[2]-y[2])
181 elif type(y) in integer_types+(float,):
182 return Vector(x[0]-y,x[1]-y,x[2]-y)
183 else:
184 return NotImplemented
185
187 x=self
188 if type(y) in integer_types+(float,):
189 return Vector(y-x[0],y-x[1],y-x[2])
190 else:
191 return NotImplemented
192
194 x=self
195 if type(y)==Vector:
196 return Vector(x[0]*y[0],x[1]*y[1],x[2]*y[2])
197 elif type(y) in integer_types+(float,):
198 return Vector(x[0]*y,x[1]*y,x[2]*y)
199 else:
200 return NotImplemented
201
203 x=self
204 if type(y) in integer_types+(float,):
205 return Vector(y*x[0],y*x[1],y*x[2])
206 else:
207 return NotImplemented
208
210 x=self
211 if type(y)==Vector:
212 return Vector(x[0]/y[0],x[1]/y[1],x[2]/y[2])
213 elif type(y) in integer_types+(float,):
214 return Vector(x[0]/y,x[1]/y,x[2]/y)
215 else:
216 return NotImplemented
217
220
222 x=self
223 if type(y)==Vector:
224 return Vector(x[1]*y[2]-x[2]*y[1],
225 x[2]*y[0]-x[0]*y[2],
226 x[0]*y[1]-x[1]*y[0])
227 else:
228 return NotImplemented
229
231 x=self
232 return math.sqrt(x[0]*x[0]+x[1]*x[1]+x[2]*x[2])
233
235 x=self
236 return Vector(-x[0],-x[1],-x[2])
237
239 x=self
240 return Vector( x[0], x[1], x[2])
241
243 - def __init__(self,v1,v2,v3,v4,v5,v6,v7,v8,v9):
245
249
251 """Wraps a boolean parsed from a file. Optionally stores a textual
252 representation
253 """
254
255 TrueStrings=["on",
256 "yes",
257 "true",
258
259 ]
260 FalseStrings=[
261 "off",
262 "no",
263 "false",
264
265 "none",
266 "invalid"
267 ]
268
269 - def __init__(self,val=None,textual=None):
294
297
298
301
303 if self.textual==None:
304 if self.val:
305 return "yes"
306 else:
307 return "no"
308 else:
309 return self.textual
310
312 if type(o) in [bool,BoolProxy]:
313 return self.val==o
314 elif isinstance(o,string_types):
315 if self.textual==o:
316 return True
317 else:
318 try:
319 return self.val==BoolProxy(textual=o)
320 except TypeError:
321 return False
322 else:
323 raise TypeError("Can't compare BoolProxy with "+str(type(o)))
324
326 """This class is in charge of handling redirections to other directories"""
327 - def __init__(self,fullCopy,reference,name):
328 self._fullCopy=fullCopy
329 self._reference=reference
330 self._name=name
331
334
335 - def getContent(self):
336 result=self._fullCopy
337 self._fullCopy=None
338 return result
339
341 return self._reference
342
344 return "$"+self._name
345
347 return float(self._reference)
348
350 """A class that acts like a dictionary, but preserves the order
351 of the entries. Used to beautify the output"""
352
354 dict.__init__(self)
355 self._order=[]
356 self._decoration={}
357 self._regex=[]
358 self._redirects=[]
359
361 isRegex=False
362 if type(key)==str:
363 if key[0]=='"' and key[-1]=='"':
364 isRegex=True
365 if isRegex:
366 exp=re.compile(key[1:-1])
367 self._regex=[(key,exp,value)]+self._regex
368 else:
369 dict.__setitem__(self,key,value)
370 if key not in self._order or isRegex:
371 self._order.append(key)
372
374 try:
375 return dict.__getitem__(self,key)
376 except KeyError:
377 for k,e,v in self._regex:
378 if e.match(key):
379 return v
380 for r in self._redirects:
381 try:
382 return r()[key]
383 except KeyError:
384 pass
385
386 raise KeyError(key)
387
389 dict.__delitem__(self,key)
390 self._order.remove(key)
391 if key in self._decoration:
392 del self._decoration[key]
393
406
408 if dict.__contains__(self,key):
409 return True
410 else:
411 for k,e,v in self._regex:
412 if e.match(key):
413 return True
414 for r in self._redirects:
415 if key in r():
416 return True
417
418 return False
419
421 if not isinstance(v,string_types) and toString:
422 r=str(v)
423 if isinstance(v,(list,dict)):
424 r='"'+r+'"'
425 return r
426 else:
427 return v
428
429 - def update(self,other=None,toString=False,**kwargs):
430 """Emulate the regular update of dict"""
431 if other:
432 if hasattr(other,"keys"):
433 for k in other.keys():
434 self[k]=self.__enforceString(other[k],toString)
435 else:
436 for k,v in other:
437 self[k]=self.__enforceString(v,toString)
438 for k in kwargs:
439 self[k]=self.__enforceString(kwargs[k],toString)
440
443
445 first=True
446 result="{"
447 for k in self.keys():
448 v=self[k]
449 if first:
450 first=False
451 else:
452 result+=", "
453 result+="%s: %s" % (repr(k),repr(v))
454 result+="}"
455 return result
456
458 if key in self:
459 if key not in self._decoration:
460 self._decoration[key]=""
461 self._decoration[key]+=text
462
464 if key in self._decoration:
465 return " \t"+self._decoration[key]
466 else:
467 return ""
468
470 for k,e,v in self._regex:
471 if k==key:
472 return v
473 raise KeyError(key)
474
479
481 """Enables Tuples to be manipulated"""
482
485
487 """A class that encapsulates an unparsed string"""
488
491
494
496 return hash(self.data)
497
499 return self.data<other.data
500
502 """Represents a part of the file with binary data in it"""
505
507 """A class that encapsulates an codestream string"""
508
511
513 """A class that encapsulates a list that was not parsed for
514 performance reasons"""
515
517 self.data=data
518 self.length=lngth
519
522
524 return cmp(self.data,other.data)
525
527 return self.data==other.data
528
530 return self.data<other.data
531
533 """A class that represents a list that is saved as binary data"""
534
537
539 """Make strings of types that might get written to a directory"""
540 if isinstance(val,(Dimension,FixedLength,BoolProxy)):
541 return str(val)
542 else:
543 return val
544
545
546 import PyFoam.Basics.FoamFileGenerator
547
548
549