/[escript]/trunk/escript/py_src/restarts.py
ViewVC logotype

Contents of /trunk/escript/py_src/restarts.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3096 - (show annotations)
Thu Aug 19 01:40:52 2010 UTC (9 years, 2 months ago) by caltinay
File MIME type: text/x-python
File size: 10930 byte(s)
-New VisIt simulation control interface in weipa (uses VisIt's simv2)
-Rewrote restarts.py to be a more generic data manager for restarts and exports
-Removed weipa python file since the functionality is now handled by restarts.py

1 ########################################################
2 #
3 # Copyright (c) 2003-2010 by University of Queensland
4 # Earth Systems Science Computational Center (ESSCC)
5 # http://www.uq.edu.au/esscc
6 #
7 # Primary Business: Queensland, Australia
8 # Licensed under the Open Software License version 3.0
9 # http://www.opensource.org/licenses/osl-3.0.php
10 #
11 ########################################################
12
13 __copyright__="""Copyright (c) 2003-2010 by University of Queensland
14 Earth Systems Science Computational Center (ESSCC)
15 http://www.uq.edu.au/esscc
16 Primary Business: Queensland, Australia"""
17 __license__="""Licensed under the Open Software License version 3.0
18 http://www.opensource.org/licenses/osl-3.0.php"""
19 __url__="https://launchpad.net/escript-finley"
20 __author__="Lutz Gross, Cihan Altinay"
21
22 """
23 an escript data import and export manager (still under development)
24
25 :var __author__: name of authors
26 :var __copyright__: copyrights
27 :var __license__: licence agreement
28 :var __url__: url entry point to documentation
29 """
30
31 import cPickle
32 import os
33 import shutil
34 import util
35 from esys.escript import getMPIRankWorld, MPIBarrierWorld, load
36
37 class DataManager(object):
38 """
39 Escript data import/export manager.
40
41 Example::
42
43 dm=DataManager(formats=[DataManager.RESTART,DataManager.VTK])
44 if dm.hasData():
45 dom = dm.getDomain()
46 time = dm.getValue("time")
47 dt = dm.getValue("dt")
48 T = dm.getValue("T")
49 u = dm.getValue("u")
50 else:
51 T = ...
52 u = ...
53 dm.addData(time=time,dt=dt,T=T,u=u) # add data and variables
54 dm.setTime(time) # set the simulation timestamp
55 dm.export() # write out data
56 """
57
58 RESTART, SILO, VISIT, VTK = range(4)
59
60 def __init__(self, formats=[RESTART], work_dir=".", restart_prefix="restart", do_restart=True):
61 """
62 Initialises the data manager. If do_restart is True and a restart
63 directory is found the contained data is loaded (hasData() returns True)
64 otherwise restart directories are removed (hasData() returns False).
65 Values are only written to disk when export() is called.
66
67 :param formats: A list of export file formats to use. Allowed values
68 are RESTART, SILO, VISIT, VTK.
69 :param work_dir: top-level directory where files are exported to
70 :param restart_prefix: prefix for restart directories. Will be used to
71 load restart files (if do_restart is True) and
72 store new restart files (if RESTART is used)
73 :param do_restart: whether to attempt to load restart files
74 """
75 self._metadata=""
76 self._md_schema=""
77 self._data={}
78 self._domain=None
79 self._stamp={}
80 self._time=0.
81 self._restartdir=None
82 self._N=-1
83 self._myrank=getMPIRankWorld()
84 self._exportformats=set(formats)
85 self._restartprefix=restart_prefix
86 self._workdir=work_dir
87 util.mkDir(self._workdir)
88 if self.VISIT in self._exportformats:
89 simFile=os.path.join(self._workdir, "escriptsim.sim2")
90 if not self.__initVisit(simFile, "Escript simulation"):
91 print "Warning: Could not initialize VisIt interface"
92 self._exportformats.remove(self.VISIT)
93 # find all restart directories
94 restart_folders = []
95 for f in os.listdir(self._workdir):
96 if f.startswith(self._restartprefix):
97 restart_folders.append(f)
98 # remove unneeded restart directories
99 if len(restart_folders)>0:
100 restart_folders.sort()
101 if do_restart:
102 self._restartdir=restart_folders[-1]
103 for f in restart_folders[:-1]:
104 self.__removeDirectory(f)
105 self.__loadState()
106 else:
107 for f in restart_folders:
108 self.__removeDirectory(f)
109
110 def addData(self, **data):
111 """
112 Adds 'escript.Data' objects and other data to be exported to this
113 manager.
114
115 :note: This method does not make copies of Data objects so
116 any modifications will be carried over until export() is called.
117 """
118 # if this is the first addition after a restart, clear data first
119 if self._restartdir != None:
120 self.__clearData()
121
122 for name,var in data.items():
123 if hasattr(var, "getDomain"):
124 if self._domain==None:
125 self._domain=var.getDomain()
126 elif self._domain != var.getDomain():
127 raise ValueError, "addData: Data must be on the same domain!"
128 self._data[name]=var
129 else:
130 self._stamp[name]=var
131
132 def hasData(self):
133 """
134 Returns True if the manager holds data for restart
135 """
136 return self._restartdir != None
137
138 def getDomain(self):
139 """
140 Returns the domain as recovered from restart files.
141 """
142 if not self.hasData():
143 raise ValueError, "No restart data available"
144 return self._domain
145
146 def getValue(self, value_name):
147 """
148 Returns an 'escript.Data' object or other value that has been loaded
149 from restart files.
150 """
151 if not self.hasData():
152 raise ValueError, "No restart data available"
153
154 if value_name in self._stamp:
155 return self._stamp[value_name]
156
157 ff=self.__getDumpFilename(value_name, self._restartdir)
158 var = load(ff, self._domain)
159 #print "Value %s recovered from %s."%(value_name, ff)
160 return var
161
162 def setTime(self, time):
163 """
164 Sets the simulation timestamp.
165 """
166 self._time = time
167
168 def setMetadataSchemaString(self, schema, metadata=""):
169 """
170 Do not use this yet.
171 """
172 self._metadata="<MetaData>"+metadata+"</MetaData>"
173 schema=""
174 for i,p in self._md_schema.items():
175 schema="%s xmlns:%s=\"%s\""%(schema, i, p)
176 self._md_schema=schema.strip()
177
178 def export(self):
179 """
180 Executes the actual data export. Depending on the formats parameter
181 used in the constructor all data added by addData() is written to disk
182 (RESTART,SILO,VTK) or made available through the VisIt simulation
183 interface (VISIT).
184 """
185
186 if self._domain == None:
187 return
188
189 idata = self.__interpolateData()
190
191 self._N += 1
192 nameprefix=os.path.join(self._workdir, "dataset%04d"%(self._N))
193
194 for f in self._exportformats:
195 if f == self.SILO:
196 from esys.weipa.weipacpp import _saveSilo
197 filename=nameprefix+".silo"
198 _saveSilo(filename, self._N, self._time, self._domain, idata)
199 elif f == self.VTK:
200 from esys.weipa.weipacpp import _saveVTK
201 filename=nameprefix+".vtu"
202 _saveVTK(filename, self._N, self._time, self._domain,
203 idata, self._metadata, self._md_schema)
204 elif f == self.VISIT:
205 from esys.weipa.weipacpp import _visitPublishData
206 _visitPublishData(self._N, self._time, self._domain, idata)
207 elif f == self.RESTART:
208 self.__saveState()
209 else:
210 raise ValueError, "export: Unknown export format "+f
211
212 self.__clearData()
213
214 def __clearData(self):
215 #print "Clearing all data"
216 self._restartdir = None
217 self._domain = None
218 self._stamp = {}
219 self._data = {}
220
221 def __getStampFilename(self, dir_name):
222 return os.path.join(self._workdir, dir_name, "stamp.%d"%self._myrank)
223
224 def __getDumpFilename(self, data_name, dir_name):
225 return os.path.join(self._workdir, dir_name, "%s.nc"%data_name)
226
227 def __initVisit(self, simFile, comment=""):
228 """
229 Initialises the VisIt interface if available.
230
231 :param simFile: Name of the sim file to be generated which can be
232 loaded into a VisIt client
233 :param comment: A short description of this simulation
234 """
235 from esys.weipa.weipacpp import _visitInitialize
236 return _visitInitialize(simFile, comment)
237
238 def __interpolateData(self):
239 # (Reduced)Solution is not directly supported so interpolate to
240 # different function space
241 from esys.escript import Solution, ReducedSolution
242 from esys.escript import ContinuousFunction, ReducedContinuousFunction
243 from esys.escript.util import interpolate
244 new_data={}
245 for n,d in self._data.items():
246 if not d.isEmpty():
247 fs=d.getFunctionSpace()
248 domain=fs.getDomain()
249 if fs == Solution(domain):
250 new_data[n]=interpolate(d, ContinuousFunction(domain))
251 elif fs == ReducedSolution(domain):
252 new_data[n]=interpolate(d, ReducedContinuousFunction(domain))
253 else:
254 new_data[n]=d
255 return new_data
256
257 def __loadState(self):
258 stamp_file=self.__getStampFilename(self._restartdir)
259 try:
260 self._stamp = cPickle.load(open(stamp_file, "rb"))
261 self._N = int(self._restartdir[len(self._restartprefix)+1:])
262 except:
263 raise IOError, "Could not load stamp file "+stamp_file
264 # load domain
265 path=os.path.join(self._workdir, self._restartdir)
266 for f in os.listdir(path):
267 if f.startswith("__mesh_finley"):
268 ff=self.__getDumpFilename("__mesh_finley",self._restartdir)
269 import esys.finley
270 self._domain = esys.finley.LoadMesh(ff)
271 #print "Domain recovered from file %s."%ff
272 break
273
274 def __saveState(self):
275 restartdir = "%s_%04d"%(self._restartprefix, self._N)
276 util.mkDir(restartdir)
277 stamp_file=self.__getStampFilename(restartdir)
278 cPickle.dump(self._stamp, open(stamp_file, "wb"))
279 ff=self.__getDumpFilename("__mesh_finley", restartdir)
280 self._domain.dump(ff)
281 #print "Domain dumped to %s."%(ff)
282 for name, var in self._data.items():
283 ff=self.__getDumpFilename(name, restartdir)
284 var.dump(ff)
285 #print "%s dumped to %s."%(name, ff)
286 # keep only one restart directory
287 old_restartdir = "%s_%04d"%(self._restartprefix, self._N-1)
288 self.__removeDirectory(old_restartdir)
289
290 def __removeDirectory(self, path):
291 if self._myrank==0 and os.path.isdir(path):
292 shutil.rmtree(path, True)
293 #print "Removed restart directory %s."%path
294 MPIBarrierWorld()
295

  ViewVC Help
Powered by ViewVC 1.1.26