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

  ViewVC Help
Powered by ViewVC 1.1.26