/[escript]/branches/mvexpr/pycad/py_src/design.py
ViewVC logotype

Contents of /branches/mvexpr/pycad/py_src/design.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4401 - (show annotations)
Fri May 10 05:14:06 2013 UTC (6 years, 5 months ago) by jfenwick
File MIME type: text/x-python
File size: 13420 byte(s)
Trying a directory swap

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

  ViewVC Help
Powered by ViewVC 1.1.26