1 |
# $Id:$ |
2 |
|
3 |
""" |
4 |
template for the Design which defines a regions and features |
5 |
for a mesh generator. |
6 |
|
7 |
@var __author__: name of author |
8 |
@var __copyright__: copyrights |
9 |
@var __license__: licence agreement |
10 |
@var __url__: url entry point on documentation |
11 |
@var __version__: version |
12 |
@var __date__: date of the version |
13 |
""" |
14 |
|
15 |
|
16 |
__author__="Lutz Gross, l.gross@uq.edu.au" |
17 |
__copyright__=""" Copyright (c) 2007 by ACcESS MNRF |
18 |
http://www.access.edu.au |
19 |
Primary Business: Queensland, Australia""" |
20 |
__license__="""Licensed under the Open Software License version 3.0 |
21 |
http://www.opensource.org/licenses/osl-3.0.php""" |
22 |
__url__="http://www.iservo.edu.au/esys/escript" |
23 |
__version__="$Revision:$" |
24 |
__date__="$Date:$" |
25 |
|
26 |
|
27 |
from primitives import Primitive, ReversePrimitive, PropertySet, Point, Manifold1D, Manifold2D, Manifold3D |
28 |
from xml.dom import minidom |
29 |
|
30 |
class TagMap(object): |
31 |
""" |
32 |
a class that allows to map tags to names |
33 |
|
34 |
tm=TagMap({5 : x }) |
35 |
tm.setMap(a=1,x=4) |
36 |
assert tm.getTags("a") == [ 1 ] |
37 |
assert tm.getTags("x") == [ 5, 4 ] |
38 |
assert tm.map(x=10., a=20.) == { 5 : 10, 4: 10, 1 : 20 } |
39 |
|
40 |
""" |
41 |
def __init__(self, map={}): |
42 |
""" |
43 |
initizlizes the mapping. map defines an initial mapping from tag to a name. |
44 |
""" |
45 |
for tag, name in map.items(): |
46 |
if not isinstance(tag, int): |
47 |
raise TypeError("tag needs to be int") |
48 |
if not isinstance(name, str): |
49 |
raise TypeError("name needs to be a str.") |
50 |
self.__map=map |
51 |
def setMap(self,**kwargs): |
52 |
""" |
53 |
set a new map where <name>=<tag> assigns the tag <tag> to name <name>. <tag> has to be integer. |
54 |
If <tag> has been assigned to a name before the mapping will be overwritten. Otherwise a new |
55 |
mapping <tag> -> <name> is set. Notice that a single name can be assigned to different tags. |
56 |
""" |
57 |
for name, tag in kwargs.items(): |
58 |
if not isinstance(tag, int): |
59 |
raise TypeError("tag needs to be int") |
60 |
self.__map[tag]=name |
61 |
def getTags(self,name=None): |
62 |
""" |
63 |
returns a list of the tags assigned to name |
64 |
""" |
65 |
if name == None: |
66 |
out=self.__map.keys() |
67 |
else: |
68 |
out=[] |
69 |
for tag, arg in self.__map.items(): |
70 |
if arg == name: out.append(tag) |
71 |
return out |
72 |
def getName(self,tag): |
73 |
""" |
74 |
returns the name of a tag |
75 |
""" |
76 |
return self.__map[tag] |
77 |
def getMapping(self): |
78 |
""" |
79 |
returns a dictionary where the tags define the keys and the values the corresposnding names. |
80 |
""" |
81 |
return self.__map |
82 |
def map(self,default=0,**kwargs): |
83 |
""" |
84 |
returns a dictionary where the tags define the keys and the values give the values assigned to the tag via name |
85 |
and kwargs: |
86 |
|
87 |
tm=TagMap(x=5) |
88 |
tm.setMap(a=1,x=4) |
89 |
print tm.map(x=10., a=20.) |
90 |
{ 5 : 10, 4: 10, 1 : 20 } |
91 |
|
92 |
the default is used for tags which map onto name with unspecified values |
93 |
""" |
94 |
out={} |
95 |
for tag in self.__map: |
96 |
if kwargs.has_key(self.__map[tag]): |
97 |
out[tag]=kwargs[self.__map[tag]] |
98 |
else: |
99 |
out[tag]=default |
100 |
return out |
101 |
|
102 |
def insert(self,data,default=0,**kwargs): |
103 |
""" |
104 |
inserts values into the L{esys.escript.Data} object according to the given values assigned to the keywords. |
105 |
the default is used for tags which map onto name with unspecified values |
106 |
""" |
107 |
d=self.map(default=default,**kwargs) |
108 |
for t,v in d.items(): |
109 |
data.setTaggedValue(t,v) |
110 |
def toDOM(self,dom): |
111 |
""" |
112 |
adds object to dom |
113 |
""" |
114 |
tm=dom.createElement("TagMap") |
115 |
dom.appendChild(tm) |
116 |
for tag,name in self.getMapping().items(): |
117 |
item_dom=dom.createElement("map") |
118 |
tag_dom=dom.createElement("tag") |
119 |
name_dom=dom.createElement("name") |
120 |
tag_dom.appendChild(dom.createTextNode(str(tag))) |
121 |
name_dom.appendChild(dom.createTextNode(str(name))) |
122 |
item_dom.appendChild(tag_dom) |
123 |
item_dom.appendChild(name_dom) |
124 |
tm.appendChild(item_dom) |
125 |
return tm |
126 |
def fromDom(self,node): |
127 |
""" |
128 |
fills from dom node |
129 |
""" |
130 |
for node in node.childNodes: |
131 |
if isinstance(node, minidom.Element): |
132 |
if node.tagName == 'map': |
133 |
tag=int(node.getElementsByTagName("tag")[0].firstChild.nodeValue.strip()) |
134 |
name=str(node.getElementsByTagName("name")[0].firstChild.nodeValue.strip()) |
135 |
self.setMap(**{ name : tag }) |
136 |
return |
137 |
|
138 |
def fillFromXML(self,xml): |
139 |
""" |
140 |
uses the xml file or string to set the mapping |
141 |
""" |
142 |
if isinstance(xml,str): |
143 |
dom=minidom.parseString(xml) |
144 |
else: |
145 |
dom=minidom.parse(xml) |
146 |
root=dom.getElementsByTagName('ESys')[0] |
147 |
for node in root.childNodes: |
148 |
if isinstance(node, minidom.Element): |
149 |
if node.tagName == 'TagMap': |
150 |
self.fromDom(node) |
151 |
return |
152 |
|
153 |
|
154 |
|
155 |
def writeXML(self,iostream=None): |
156 |
""" |
157 |
writes XML serialization into the iostream or if not present returns the XML as string |
158 |
""" |
159 |
dom=minidom.Document() |
160 |
esys=dom.createElement('ESys') |
161 |
esys.appendChild(self.toDOM(dom)) |
162 |
dom.appendChild(esys) |
163 |
if iostream == None: |
164 |
return dom.toprettyxml() |
165 |
else: |
166 |
iostream.write(dom.toprettyxml()) |
167 |
|
168 |
class Design(object): |
169 |
""" |
170 |
template for a design which defines the input for a mesh generator |
171 |
""" |
172 |
def __init__(self,dim=3,element_size=1.,order=1,keep_files=False): |
173 |
""" |
174 |
initializes a design |
175 |
|
176 |
@param dim: patial dimension |
177 |
@element_size: global element size |
178 |
@order: element order |
179 |
@keep_files: flag to keep work files. |
180 |
""" |
181 |
self.clearItems() |
182 |
self.setElementSize(element_size) |
183 |
self.setDim(dim) |
184 |
self.setElementOrder(order) |
185 |
if keep_files: |
186 |
self.setKeepFilesOn() |
187 |
else: |
188 |
self.setKeepFilesOff() |
189 |
def setDim(self,dim=3): |
190 |
""" |
191 |
sets the spatial dimension |
192 |
""" |
193 |
if not dim in [1,2,3]: |
194 |
raise ValueError("only dimension 1, 2, 3 are supported.") |
195 |
self.__dim=dim |
196 |
def getDim(self,dim=3): |
197 |
""" |
198 |
returns the spatial dimension |
199 |
""" |
200 |
return self.__dim |
201 |
def setElementOrder(self,order=1): |
202 |
""" |
203 |
sets the element order |
204 |
""" |
205 |
if not order in [1,2]: |
206 |
raise ValueError("only element orser 1 or 2 is supported.") |
207 |
self.__order=order |
208 |
def getElementOrder(self,order=1): |
209 |
""" |
210 |
returns the element order |
211 |
""" |
212 |
return self.__order |
213 |
def setElementSize(self,element_size=0.1): |
214 |
""" |
215 |
set the global element size. |
216 |
""" |
217 |
if element_size<=0.: |
218 |
raise ValueError("element size needs to be non--negative.") |
219 |
self.__element_size=element_size |
220 |
def getElementSize(self,element_size=1.): |
221 |
""" |
222 |
returns the global element size. |
223 |
""" |
224 |
return self.__element_size |
225 |
def setKeepFilesOn(self): |
226 |
""" |
227 |
work files are kept at the end of the generation |
228 |
""" |
229 |
self.__keep_files=True |
230 |
def setKeepFilesOff(self): |
231 |
""" |
232 |
work files are deleted at the end of the generation |
233 |
""" |
234 |
self.__keep_files=False |
235 |
def keepFiles(self): |
236 |
""" |
237 |
returns True if work files are kept |
238 |
""" |
239 |
return self.__keep_files |
240 |
def addItems(self,*items): |
241 |
""" |
242 |
adds items to the design |
243 |
""" |
244 |
for i in range(len(items)): |
245 |
if not isinstance(items[i],(Primitive, ReversePrimitive)): |
246 |
raise TypeError("%s-th argument is not a Primitive object"%i) |
247 |
for i in items: |
248 |
self.__items.append(i) |
249 |
def getItems(self): |
250 |
""" |
251 |
returns a list of the items used in the design |
252 |
""" |
253 |
return self.__items |
254 |
def clearItems(self): |
255 |
""" |
256 |
resets the items in design |
257 |
""" |
258 |
self.__items=[] |
259 |
def getAllPrimitives(self): |
260 |
""" |
261 |
returns a list of all primitives used to create the design. |
262 |
each primitve appears once. The primitives are ordered by their |
263 |
order of generation |
264 |
""" |
265 |
prims=set() |
266 |
for i in self.getItems(): prims|=set(i.getPrimitives()) |
267 |
prims=list(prims) |
268 |
prims.sort() |
269 |
return prims |
270 |
|
271 |
def setOptions(self,**kwargs): |
272 |
""" |
273 |
sets options of the mesh generator |
274 |
|
275 |
@note: this method is typically overwritten by a particular Design implementation |
276 |
""" |
277 |
pass |
278 |
def getMeshHandler(self): |
279 |
""" |
280 |
returns a handle to a mesh meshing the design |
281 |
|
282 |
@note: this method has to be overwritten by a particular Design implementation |
283 |
""" |
284 |
raise NotImplementedError() |
285 |
|
286 |
def getPointTagMap(self): |
287 |
""" |
288 |
returns a L{TagMap} to map the name of L{Point} L{PropertySet}s to tags |
289 |
""" |
290 |
m={} |
291 |
for p in self.getAllPrimitives(): |
292 |
if isinstance(p, PropertySet): |
293 |
if p.getDim() == 0: m[ p.getTag() ] = p.getName() |
294 |
return TagMap(m) |
295 |
def getCurveTagMap(self): |
296 |
""" |
297 |
returns a L{TagMap} to map the name of L{Manifold1D} L{PropertySet}s to tags |
298 |
""" |
299 |
m={} |
300 |
for p in self.getAllPrimitives(): |
301 |
if isinstance(p, PropertySet): |
302 |
if p.getDim() == 1: m[ p.getTag() ] = p.getName() |
303 |
return TagMap(m) |
304 |
def getSurfaceTagMap(self): |
305 |
""" |
306 |
returns a L{TagMap} to map the name of L{Manifold2D} L{PropertySet}s to tags |
307 |
""" |
308 |
m={} |
309 |
for p in self.getAllPrimitives(): |
310 |
if isinstance(p, PropertySet): |
311 |
if p.getDim() == 2: m[ p.getTag() ] = p.getName() |
312 |
return TagMap(m) |
313 |
def getVolumeTagMap(self): |
314 |
""" |
315 |
returns a L{TagMap} to map the name of L{Manifold3D} L{PropertySet}s to tags |
316 |
""" |
317 |
m={} |
318 |
for p in self.getAllPrimitives(): |
319 |
if isinstance(p, PropertySet): |
320 |
if p.getDim() == 3: m[ p.getTag() ] = p.getName() |
321 |
return TagMap(m) |