Package PyFoam :: Package RunDictionary :: Module SolutionDirectory
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.RunDictionary.SolutionDirectory

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