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

Source Code for Module PyFoam.RunDictionary.SolutionDirectory

  1  #  ICE Revision: $Id: SolutionDirectory.py 7832 2007-08-28 13:07:26Z 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 
  8  import tarfile,fnmatch 
  9   
10 -class SolutionDirectory(Utilities):
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
37 - def isValid(self):
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
53 - def addToClone(self,name):
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
58 - def cloneCase(self,name,svnRemove=True):
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
117 - def reread(self):
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
143 - def sorttimes(self,x,y):
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
153 - def getTimes(self):
154 """ @return: List of all the available times""" 155 self.reread() 156 return self.times
157
158 - def addBackup(self,pth):
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
163 - def getLast(self):
164 """@return: the last time for which a solution exists 165 @rtype: str""" 166 self.reread() 167 return self.last
168
169 - def lastToArchive(self,name):
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
187 - def clearResults(self,after=None):
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
203 - def clearPattern(self,glob):
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
209 - def clearOther(self,processor=True,pyfoam=True):
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
228 - def initialDir(self):
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
237 - def latestDir(self):
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
248 - def constantDir(self,region=None):
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
257 - def systemDir(self,region=None):
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
266 - def controlDict(self):
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
272 - def polyMeshDir(self,region=None):
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
278 - def boundaryDict(self,region=None):
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
284 - def blockMesh(self,region=None):
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
295 - def makeFile(self,name):
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
303 - def getRegions(self):
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
314 -class ChemkinSolutionDirectory(SolutionDirectory):
315 """Solution directory with a directory for the Chemkin-files""" 316 317 chemkinName = "chemkin" 318
319 - def __init__(self,name,archive="ArchiveDir"):
320 SolutionDirectory.__init__(self,name,archive=archive) 321 322 self.addToClone(self.chemkinName)
323
324 - def chemkinDir(self):
325 """@rtype: str 326 @return: The directory with the Chemkin-Files""" 327 328 return path.join(self.name,self.chemkinName)
329