/[escript]/trunk/pycad/py_src/design.py
ViewVC logotype

Contents of /trunk/pycad/py_src/design.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2717 - (show annotations)
Wed Oct 14 03:41:20 2009 UTC (10 years, 5 months ago) by gross
File MIME type: text/x-python
File size: 13173 byte(s)
implements https://mantis.esscc.uq.edu.au/view.php?id=426
1
2 ########################################################
3 #
4 # Copyright (c) 2003-2009 by University of Queensland
5 # Earth Systems Science Computational Center (ESSCC)
6 # http://www.uq.edu.au/esscc
7 #
8 # Primary Business: Queensland, Australia
9 # Licensed under the Open Software License version 3.0
10 # http://www.opensource.org/licenses/osl-3.0.php
11 #
12 ########################################################
13
14 __copyright__="""Copyright (c) 2003-2009 by University of Queensland
15 Earth Systems Science Computational Center (ESSCC)
16 http://www.uq.edu.au/esscc
17 Primary Business: Queensland, Australia"""
18 __license__="""Licensed under the Open Software License version 3.0
19 http://www.opensource.org/licenses/osl-3.0.php"""
20 __url__="https://launchpad.net/escript-finley"
21
22 """
23 Template for the Design which defines regions and features
24 for a mesh generator.
25
26 :var __author__: name of author
27 :var __copyright__: copyrights
28 :var __license__: licence agreement
29 :var __url__: url entry point on documentation
30 :var __version__: version
31 :var __date__: date of the version
32 """
33
34 __author__="Lutz Gross, l.gross@uq.edu.au"
35
36 from primitives import Primitive, ReversePrimitive, PropertySet, Point, Manifold1D, Manifold2D, Manifold3D
37 from xml.dom import minidom
38
39 class TagMap(object):
40 """
41 A class that allows to map tags to names.
42
43 Example::
44
45 tm=TagMap({5 : x })
46 tm.setMap(a=1,x=4)
47 assert tm.getTags("a") == [ 1 ]
48 assert tm.getTags("x") == [ 5, 4 ]
49 assert tm.map(x=10., a=20.) == { 5 : 10, 4: 10, 1 : 20 }
50
51 """
52 def __init__(self, mapping={}):
53 """
54 Initializes the mapping. ``mapping`` defines an initial mapping from tag
55 to a name.
56 """
57 self.__mapping={}
58 for tag, name in mapping.items():
59 if not isinstance(tag, int):
60 raise TypeError("tag needs to be an int")
61 if not isinstance(name, str):
62 raise TypeError("name needs to be a str.")
63 self.__mapping[tag]=name
64
65 def setMap(self,**kwargs):
66 """
67 Sets a new map where <name>=<tag> assigns the tag <tag> to name <name>.
68 <tag> has to be an integer. If <tag> has been assigned to a name before
69 the mapping will be overwritten. Otherwise a new mapping <tag> -> <name>
70 is set. Notice that a single name can be assigned to different tags.
71 """
72 for name, tag in kwargs.items():
73 if not isinstance(tag, int):
74 raise TypeError("tag needs to be an int")
75 self.__mapping[tag]=name
76
77 def getTags(self,name=None):
78 """
79 Returns a list of the tags assigned to ``name``. If name is not present
80 a list of all tags is returned.
81 """
82 if name == None:
83 out=self.__mapping.keys()
84 else:
85 out=[]
86 for tag, arg in self.__mapping.items():
87 if arg == name: out.append(tag)
88 return out
89
90 def getName(self,tag=None):
91 """
92 Returns the name of a tag. If ``tag`` is not present a list of all names
93 is returned.
94 """
95 if tag == None:
96 return list(set(self.__mapping.values()))
97 else:
98 return self.__mapping[tag]
99
100 def getMapping(self):
101 """
102 Returns a dictionary where the tags define the keys and the values the
103 corresponding names.
104 """
105 return self.__mapping
106
107 def map(self,default=0,**kwargs):
108 """
109 Returns a dictionary where the tags define the keys and the values give
110 the values assigned to the tag via name and kwargs::
111
112 tm=TagMap(x=5)
113 tm.setMap(a=1,x=4)
114 print tm.map(x=10., a=20.)
115 { 5 : 10, 4: 10, 1 : 20 }
116
117 The default is used for tags which map onto name with unspecified
118 values.
119 """
120 out={}
121 for tag in self.__mapping:
122 if kwargs.has_key(self.__mapping[tag]):
123 out[tag]=kwargs[self.__mapping[tag]]
124 else:
125 out[tag]=default
126 return out
127
128 def insert(self,data,default=0,**kwargs):
129 """
130 Inserts values into the `esys.escript.Data` object according to the
131 given values assigned to the keywords. The default is used for tags
132 which map onto name with unspecified values.
133 """
134 d=self.map(default=default,**kwargs)
135 for t,v in d.items():
136 data.setTaggedValue(t,v)
137
138 def passToDomain(self,domain):
139 """
140 Passes the tag map to the `esys.escript.Domain` ``domain``.
141 """
142 for tag, name in self.__mapping.items():
143 print "Tag",name, "is mapped to id ", tag
144 domain.setTagMap(name,tag)
145
146 def toDOM(self,dom):
147 """
148 Adds object to ``dom``.
149 """
150 tm=dom.createElement("TagMap")
151 dom.appendChild(tm)
152 for tag,name in self.getMapping().items():
153 item_dom=dom.createElement("map")
154 tag_dom=dom.createElement("tag")
155 name_dom=dom.createElement("name")
156 tag_dom.appendChild(dom.createTextNode(str(tag)))
157 name_dom.appendChild(dom.createTextNode(str(name)))
158 item_dom.appendChild(tag_dom)
159 item_dom.appendChild(name_dom)
160 tm.appendChild(item_dom)
161 return tm
162
163 def fromDom(self,node):
164 """
165 Fills names and tags from dom ``node``.
166 """
167 for node in node.childNodes:
168 if isinstance(node, minidom.Element):
169 if node.tagName == 'map':
170 tag=int(node.getElementsByTagName("tag")[0].firstChild.nodeValue.strip())
171 name=str(node.getElementsByTagName("name")[0].firstChild.nodeValue.strip())
172 self.setMap(**{ name : tag })
173 return
174
175 def fillFromXML(self,iostream):
176 """
177 Uses the XML file or string to set the mapping.
178 """
179 if isinstance(iostream,str):
180 dom=minidom.parseString(iostream)
181 else:
182 dom=minidom.parse(iostream)
183 root=dom.getElementsByTagName('ESys')[0]
184 for node in root.childNodes:
185 if isinstance(node, minidom.Element):
186 if node.tagName == 'TagMap':
187 self.fromDom(node)
188 return
189
190 def writeXML(self,iostream=None):
191 """
192 Serializes self as XML into ``iostream`` or if not present returns the
193 XML as string.
194 """
195 dom=minidom.Document()
196 esys=dom.createElement('ESys')
197 esys.appendChild(self.toDOM(dom))
198 dom.appendChild(esys)
199 if iostream == None:
200 return dom.toprettyxml()
201 else:
202 iostream.write(dom.toprettyxml())
203
204 class Design(object):
205 """
206 Template for a design which defines the input for a mesh generator.
207
208 :cvar GMSH: U{gmsh<http://www.geuz.org/gmsh/>} file formatt
209 :cvar IDEAS: U{I_DEAS<http://www.plm.automation.siemens.com/en_us/products/nx/>} universal file format
210 :cvar VRML: U{VRML<http://www.w3.org/MarkUp/VRML/>} file format
211 :cvar STL: U{STL<http://en.wikipedia.org/wiki/STL_(file_format)>} file format
212 :cvar NASTRAN: U{Nastran<http://simcompanion.mscsoftware.com/infocenter/index?page=content&channel=DOCUMENTATION>} bulk data format
213 :cvar MEDIT: U{Medit<http://www-rocq.inria.fr/OpenFEM/Doc/>} file format
214 :cvar CGNS: U{CGNS<http://cgns.sourceforge.net/>} file format
215 :cvar PLOT3D: U{Plot3D<http://www.plot3d.net/>} file format
216 :cvar DIFFPACK: U{Diffpack<http://www.diffpack.com/>} file format
217 """
218 GMSH="msh"
219 IDEAS="unv"
220 VRML="vrml"
221 STL="stl"
222 NASTRAN="bdf"
223 MEDIT="mesh"
224 CGNS="cgns"
225 PLOT3D="p3d"
226 DIFFPACK="diff"
227 def __init__(self,dim=3,element_size=1.,order=1,keep_files=False):
228 """
229 Initializes a design.
230
231 :param dim: spatial dimension
232 :param element_size: global element size
233 :param order: element order
234 :param keep_files: flag to keep work files
235 """
236 self.clearItems()
237 self.setElementSize(element_size)
238 self.setDim(dim)
239 self.setElementOrder(order)
240 self.setFileFormat()
241 self.setMeshFileName()
242 if keep_files:
243 self.setKeepFilesOn()
244 else:
245 self.setKeepFilesOff()
246
247 def setDim(self,dim=3):
248 """
249 Sets the spatial dimension.
250 """
251 if not dim in [1,2,3]:
252 raise ValueError("only dimension 1, 2, 3 are supported.")
253 self.__dim=dim
254
255 def getDim(self,dim=3):
256 """
257 Returns the spatial dimension.
258 """
259 return self.__dim
260
261 def setElementOrder(self,order=1):
262 """
263 Sets the element order.
264 """
265 if not order in [1,2]:
266 raise ValueError("only element order 1 or 2 is supported.")
267 self.__order=order
268
269 def getElementOrder(self):
270 """
271 Returns the element order.
272 """
273 return self.__order
274
275 def setElementSize(self,element_size=1.):
276 """
277 Sets the global element size.
278 """
279 if element_size<=0.:
280 raise ValueError("element size needs to be positive.")
281 self.__element_size=element_size
282
283 def getElementSize(self):
284 """
285 Returns the global element size.
286 """
287 return self.__element_size
288
289 def setKeepFilesOn(self):
290 """
291 Work files are kept at the end of the generation.
292 """
293 self.__keep_files=True
294
295 def setKeepFilesOff(self):
296 """
297 Work files are deleted at the end of the generation
298 """
299 self.__keep_files=False
300
301 def keepFiles(self):
302 """
303 Returns True if work files are kept, False otherwise.
304 """
305 return self.__keep_files
306
307 def addItems(self,*items):
308 """
309 Adds items to the design.
310 """
311 new_items=[]
312 for i in range(len(items)):
313 if not isinstance(items[i],(Primitive, ReversePrimitive)):
314 raise TypeError("%s-th argument is not a Primitive object"%i)
315 if isinstance(items[i],PropertySet):
316 q=items[i]
317 else:
318 q=PropertySet("__%s__"%(items[i].getID()), items[i])
319 for p in self.getAllPrimitives():
320 if isinstance(p, PropertySet):
321 if q.getName() == p.getName():
322 raise ValueError("Property set name %s is allready in use."%q.getName())
323 new_items.append(q)
324 for q in new_items: self.__items.append(q)
325
326 def getItems(self):
327 """
328 Returns a list of the items used in the design.
329 """
330 return self.__items
331
332 def clearItems(self):
333 """
334 Removes all items from the design.
335 """
336 self.__items=[]
337
338 def getAllPrimitives(self):
339 """
340 Returns a list of all primitives used to create the design.
341 Each primitive appears once. The primitives are ordered by their
342 order of generation.
343 """
344 prims=[]
345 for i in self.getItems():
346 for p in i.getPrimitives():
347 if not p in prims: prims.append(p)
348 prims.sort()
349 return prims
350
351 def setOptions(self,**kwargs):
352 """
353 Sets options of the mesh generator.
354
355 :note: this method is typically overwritten by a particular design
356 implementation.
357 """
358 pass
359 def generate(self):
360 """
361 generate output file
362
363 :note: this method may be overwritten by a particular design
364 implementation.
365 """
366 self.getMeshHandler()
367
368 def getMeshHandler(self):
369 """
370 Returns a handle to a mesh meshing the design.
371
372 :note: this method has to be overwritten by a particular design
373 implementation.
374 """
375 raise NotImplementedError()
376
377 def getTagMap(self):
378 """
379 Returns a `TagMap` to map the names of `PropertySet` s to tags.
380 """
381 m={}
382 for p in self.getAllPrimitives():
383 if isinstance(p, PropertySet): m[ p.getTag() ] = p.getName()
384 return TagMap(m)
385
386 def setFileFormat(self,format='msh'):
387 """
388 Sets the file format to be used.
389
390 :param format: format to be used. needs to be one of
391
392 """
393 if not format in [ self.GMSH, self.IDEAS, self.VRML, self.STL, self.NASTRAN, self.MEDIT, self.CGNS, self.PLOT3D, self.DIFFPACK] :
394 raise ValueError,"unknown file format %s."%format
395 self.__fileformat=format
396
397 def getFileFormat(self):
398 """
399 Returns the file format
400 """
401 return self.__fileformat
402
403 def setMeshFileName(self, name=None):
404 """
405 Sets the name for the mesh file. If no name is given a name is generated.
406 """
407 if name == None:
408 tmp_f_id=tempfile.mkstemp(suffix="."+self.getFileFormat())
409 self.__mshname=tmp_f_id[1]
410 os.close(tmp_f_id[0])
411 else:
412 self.__mshname=name
413 self.setKeepFilesOn()
414
415 def getMeshFileName(self):
416 """
417 Returns the name of the mesh file.
418 """
419 return self.__mshname
420
421
422

  ViewVC Help
Powered by ViewVC 1.1.26