1
2 """Working with a solution directory"""
3
4 from PyFoam.Basics.Utilities import Utilities
5 from PyFoam.Basics.BasicFile import BasicFile
6
7 from os import listdir,path,mkdir
8 import tarfile,fnmatch
9
11 """Represents a solution directory
12
13 In the solution directory subdirectories whose names are numbers
14 are assumed to be solutions for a specific time-step
15
16 A sub-directory (called the Archive) is created to which solution
17 data is copied"""
18
19 - def __init__(self,name,archive="ArchiveDir"):
20 """@param name: Name of the solution directory
21 @param archive: name of the directory where the lastToArchive-method
22 should copy files, if None no archive is created"""
23
24 self.name=name
25 self.archive=None
26 if archive!=None:
27 self.archive=path.join(name,archive)
28 if not path.exists(self.archive):
29 mkdir(self.archive)
30
31 self.backups=[]
32
33 self.reread()
34
35 self.essential=[self.systemDir(),self.constantDir(),self.initialDir()]
36
38 """Checks whether this is a valid case directory by looking for
39 the system- and constant-directories and the controlDict-file"""
40 if not path.exists(self.systemDir()):
41 return False
42 elif not path.isdir(self.systemDir()):
43 return False
44 elif not path.exists(self.constantDir()):
45 return False
46 elif not path.isdir(self.constantDir()):
47 return False
48 elif not path.exists(self.controlDict()):
49 return False
50 else:
51 return True
52
54 """add directory to the list that is needed to clone this case
55 @param name: name of the subdirectory (the case directory is prepended)"""
56 self.essential.append(path.join(self.name,name))
57
59 """create a clone of this case directory. Remove the target directory, if it already exists
60
61 @param name: Name of the new case directory
62 @param svnRemove: Look for .svn-directories and remove them
63 @rtype: L{SolutionDirectory} or correct subclass
64 @return: The target directory"""
65
66 if path.exists(name):
67 self.execute("rm -r "+name)
68 mkdir(name)
69 for d in self.essential:
70 self.execute("cp -r "+d+" "+name)
71
72 if svnRemove:
73 self.execute("find "+name+" -name .svn -exec rm -rf {} \\; -prune")
74
75 return self.__class__(name)
76
77 - def packCase(self,tarname,last=False,exclude=[],additional=[]):
78 """Packs all the important files into a compressed tarfile.
79 Uses the essential-list and excludes the .svn-directories.
80 Also excludes files ending with ~
81 @param tarname: the name of the tar-file
82 @param last: add the last directory to the list of directories to be added
83 @param exclude: List with additional glob filename-patterns to be excluded
84 @param additional: List with additional glob filename-patterns
85 that are to be added"""
86
87 ex=["*~",".svn"]+exclude
88 members=self.essential[:]
89 if last:
90 if self.getLast()!=self.first:
91 members.append(self.latestDir())
92 for p in additional:
93 for f in listdir(self.name):
94 if (f not in members) and fnmatch.fnmatch(f,p):
95 members.append(path.join(self.name,f))
96
97 tar=tarfile.open(tarname,"w:gz")
98
99 for m in members:
100 self.addToTar(tar,m,exclude=ex)
101
102 tar.close()
103
104 - def addToTar(self,tar,name,exclude=[]):
105 """The workhorse for the packCase-method"""
106
107 for e in exclude:
108 if fnmatch.fnmatch(path.basename(name),e):
109 return
110
111 if path.isdir(name):
112 for m in listdir(name):
113 self.addToTar(tar,path.join(name,m),exclude=exclude)
114 else:
115 tar.add(name)
116
118 """Rescan the directory for the time directories"""
119 self.times=[]
120 self.first=None
121 self.last=None
122
123 for f in listdir(self.name):
124 try:
125 val=float(f)
126 self.times.append(f)
127 if self.first==None:
128 self.first=f
129 else:
130 if float(f)<float(self.first):
131 self.first=f
132 if self.last==None:
133 self.last=f
134 else:
135 if float(f)>float(self.last):
136 self.last=f
137
138 except ValueError:
139 pass
140
141 self.times.sort(self.sorttimes)
142
144 """Sort function for the solution files"""
145 if(float(x)==float(y)):
146 return 0
147 elif float(x)<float(y):
148 return -1
149 else:
150 return 1
151
152
154 """ @return: List of all the available times"""
155 self.reread()
156 return self.times
157
159 """add file to list of files that are to be copied to the
160 archive"""
161 self.backups.append(path.join(self.name,pth))
162
164 """@return: the last time for which a solution exists
165 @rtype: str"""
166 self.reread()
167 return self.last
168
170 """copy the last solution (plus the backup-files to the
171 archive)
172
173 @param name: name of the sub-directory in the archive"""
174 if self.archive==None:
175 print "Warning: nor Archive-directory"
176 return
177
178 self.reread()
179 fname=path.join(self.archive,name)
180 if path.exists(fname):
181 self.execute("rm -r "+fname)
182 mkdir(fname)
183 self.execute("cp -r "+path.join(self.name,self.last)+" "+fname)
184 for f in self.backups:
185 self.execute("cp -r "+f+" "+fname)
186
188 """remove all time-directories after a certain time. If not time ist
189 set the initial time is used
190 @param after: time after which directories ar to be removed"""
191
192 self.reread()
193
194 if after==None:
195 time=float(self.first)
196 else:
197 time=float(after)
198
199 for f in self.times:
200 if float(f)>time:
201 self.execute("rm -r "+path.join(self.name,f))
202
204 """Clear all files that fit a certain shell (glob) pattern
205 @param glob: the pattern which the files are going to fit"""
206
207 self.execute("rm -rf "+path.join(self.name,glob))
208
210 """Remove additional directories
211 @param processor: remove the processorXX directories
212 @param pyfoam: rremove all directories typically created by PyFoam"""
213
214 if processor:
215 self.clearPattern("processor?*")
216 if pyfoam:
217 self.clearPattern("PyFoam.?*")
218 self.clearPattern("*?.analyzed")
219
220 - def clear(self,after=None,processor=True,pyfoam=True):
221 """One-stop-shop to remove data
222 @param after: time after which directories ar to be removed
223 @param processor: remove the processorXX directories
224 @param pyfoam: rremove all directories typically created by PyFoam"""
225 self.clearResults(after=after)
226 self.clearOther(processor=processor,pyfoam=pyfoam)
227
229 """@return: the name of the first time-directory (==initial
230 conditions
231 @rtype: str"""
232 if self.first:
233 return path.join(self.name,self.first)
234 else:
235 return None
236
238 """@param region: Specify the region for cases with more than 1 mesh
239 @return: the name of the first last-directory (==simulation
240 results)
241 @rtype: str"""
242 last=self.getLast()
243 if last:
244 return path.join(self.name,last)
245 else:
246 return None
247
249 """@param region: Specify the region for cases with more than 1 mesh
250 @return: the name of the C{constant}-directory
251 @rtype: str"""
252 if region:
253 return path.join(self.name,"constant",region)
254 else:
255 return path.join(self.name,"constant")
256
258 """@param region: Specify the region for cases with more than 1 mesh
259 @return: the name of the C{system}-directory
260 @rtype: str"""
261 if region:
262 return path.join(self.name,"system",region)
263 else:
264 return path.join(self.name,"system")
265
267 """@param region: Specify the region for cases with more than 1 mesh
268 @return: the name of the C{controlDict}
269 @rtype: str"""
270 return path.join(self.systemDir(),"controlDict")
271
273 """@param region: Specify the region for cases with more than 1 mesh
274 @return: the name of the C{polyMesh}
275 @rtype: str"""
276 return path.join(self.constantDir(region=region),"polyMesh")
277
279 """@param region: Specify the region for cases with more than 1 mesh
280 @return: name of the C{boundary}-file
281 @rtype: str"""
282 return path.join(self.polyMeshDir(region=region),"boundary")
283
285 """@param region: Specify the region for cases with more than 1 mesh
286 @return: the name of the C{blockMeshDict} if it exists. Returns
287 an empty string if it doesn't
288 @rtype: str"""
289 p=path.join(self.polyMeshDir(region=region),"blockMeshDict")
290 if path.exists(p):
291 return p
292 else:
293 return ""
294
296 """create a file in the solution directory and return a
297 corresponding BasicFile-object
298
299 @param name: Name of the file
300 @rtype: L{BasicFile}"""
301 return BasicFile(path.join(self.name,name))
302
304 """Gets a list of all the available mesh regions by checking all
305 directories in constant and using all those that have a polyMesh-subdirectory"""
306 lst=[]
307 for d in self.listDirectory(self.constantDir()):
308 if path.isdir(path.join(self.constantDir(),d)):
309 if path.exists(self.polyMeshDir(region=d)):
310 lst.append(d)
311 lst.sort()
312 return lst
313
315 """Solution directory with a directory for the Chemkin-files"""
316
317 chemkinName = "chemkin"
318
319 - def __init__(self,name,archive="ArchiveDir"):
323
325 """@rtype: str
326 @return: The directory with the Chemkin-Files"""
327
328 return path.join(self.name,self.chemkinName)
329