1 |
\chapter{The module \pycad} |
\chapter{The module \pycad} |
2 |
\label{PYCAD CHAP} |
\label{PYCAD CHAP} |
3 |
|
|
4 |
\declaremodule{extension}{pyvisi} |
|
5 |
|
|
6 |
|
\section{Introduction} |
7 |
|
|
8 |
|
|
9 |
|
\section{\pycad Classes} |
10 |
|
\declaremodule{extension}{esys.pycad} |
11 |
\modulesynopsis{Python geometry description and meshing interface} |
\modulesynopsis{Python geometry description and meshing interface} |
12 |
|
|
13 |
|
\subsection{Primitives} |
14 |
|
|
15 |
|
\begin{classdesc}{Point}{} |
16 |
|
|
17 |
|
\end{classdesc} |
18 |
|
|
19 |
|
\begin{classdesc}{Manifold1D}{} |
20 |
|
|
21 |
|
\end{classdesc} |
22 |
|
|
23 |
|
\begin{classdesc}{Manifold2D}{} |
24 |
|
|
25 |
|
\end{classdesc} |
26 |
|
|
27 |
|
\begin{classdesc}{Manifold3D}{} |
28 |
|
|
29 |
|
\end{classdesc} |
30 |
|
|
31 |
|
%============================================================================================================ |
32 |
|
\subsection{Transformations} |
33 |
|
|
34 |
|
Transformations are used to move geometrical objects in the 3-dimensional space: |
35 |
|
|
36 |
|
\begin{datadesc}{DEG} |
37 |
|
The unit of degree. For instance use \code{90*DEG} for $90$ degrees. |
38 |
|
\end{datadesc} |
39 |
|
|
40 |
|
\begin{datadesc}{RAD} |
41 |
|
The unit of radiant. For instance use \code{math.pi*RAD} for $180$ degrees. |
42 |
|
\end{datadesc} |
43 |
|
|
44 |
|
\begin{classdesc}{Translation}{\optional{b=[0,0,0]}} |
45 |
|
defines a translation $x \to x+b$. \var{b} can be any object that can be converted |
46 |
|
into a \numarray object of shape $(3,)$. |
47 |
|
\end{classdesc} |
48 |
|
|
49 |
|
\begin{classdesc}{Rotatation}{\optional{axis=[1,1,1], \optional{ point = [0,0,0], \optional{angle=0*RAD} } } } |
50 |
|
defines a rotation by \var{angle} around axis through point \var{point} and direction \var{axis}. |
51 |
|
\var{axis} and \var{point} can be any object that can be converted |
52 |
|
into a \numarray object of shape $(3,)$. |
53 |
|
\var{axis} does not have to be normalized but must have positive length. The right hand rule~\cite{RIGHTHANDRULE} |
54 |
|
applies. |
55 |
|
\end{classdesc} |
56 |
|
|
57 |
|
|
58 |
|
\begin{classdesc}{Dilation}{\optional{factor=1., \optional{center=[0,0,0]}}} |
59 |
|
defines a dilation by the expansion/contraction \var{factor} with |
60 |
|
\var{center} as the dilation center. |
61 |
|
\var{center} can be any object that can be converted |
62 |
|
into a \numarray object of shape $(3,)$. |
63 |
|
\end{classdesc} |
64 |
|
|
65 |
|
\begin{classdesc}{Reflection}{\optional{normal=[1,1,1], \optional{offset=0}}} |
66 |
|
defines a reflection on a plane defined in normal form $n^t x = d$ |
67 |
|
where $n$ is the surface normal \var{normal} and $d$ is the plane \var{offset}. |
68 |
|
\var{normal} can be any object that can be converted |
69 |
|
into a \numarray object of shape $(3,)$. |
70 |
|
\var{normal} does not have to be normalized but must have positive length. |
71 |
|
\end{classdesc} |
72 |
|
|
73 |
|
\subsection{Properties} |
74 |
|
|
75 |
|
Property sets are used to bundle a set of geometrical objects in a group. The group |
76 |
|
is identified by a name. Typically a property set is used to mark |
77 |
|
subregions with share the same material properties or to mark portions of the boundary. |
78 |
|
For efficiency, the \Design class object assigns a integer to each of its property sets, |
79 |
|
a so-called tag \index{tag}. The appropriate tag is attached to the elements at generation time. |
80 |
|
The \TagMap generated by the \Design allows mapping the a name onto the corresponding tag. |
81 |
|
In order to avoid ambiguity it is recommended to have unique names of property sets within a \Design. |
82 |
|
|
83 |
|
|
84 |
|
\begin{classdesc}{PropertySet}{name,*items} |
85 |
|
defines a group geometrical objects which can be accessed through a \var{name} |
86 |
|
The objects in the tuple \var{items} mast all be \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD objects. |
87 |
|
\end{classdesc} |
88 |
|
|
89 |
|
|
90 |
|
\begin{methoddesc}[PropertySet]{getManifoldClass}{} |
91 |
|
returns the manifold class \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD expected from the items |
92 |
|
in the property set. |
93 |
|
\end{methoddesc} |
94 |
|
|
95 |
|
\begin{methoddesc}[PropertySet]{getDim}{} |
96 |
|
returns the spatial dimension of the items |
97 |
|
in the property set. |
98 |
|
\end{methoddesc} |
99 |
|
|
100 |
|
\begin{methoddesc}[PropertySet]{getName}{} |
101 |
|
returns the name of the set |
102 |
|
\end{methoddesc} |
103 |
|
|
104 |
|
\begin{methoddesc}[PropertySet]{setName}{name} |
105 |
|
sets the name. This name should be unique within a \Design. |
106 |
|
\end{methoddesc} |
107 |
|
|
108 |
|
\begin{methoddesc}[PropertySet]{addItem}{*items} |
109 |
|
adds a tuple of items. They need to be objects of class \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD. |
110 |
|
\end{methoddesc} |
111 |
|
|
112 |
|
\begin{methoddesc}[PropertySet]{getItems}{} |
113 |
|
returns the list of items |
114 |
|
\end{methoddesc} |
115 |
|
|
116 |
|
\begin{methoddesc}[PropertySet]{clearItems}{} |
117 |
|
clears the list of items |
118 |
|
\end{methoddesc} |
119 |
|
|
120 |
|
\begin{methoddesc}[PropertySet]{getTag}{} |
121 |
|
returns the tag used for this property set |
122 |
|
\end{methoddesc} |
123 |
|
|
124 |
|
\subsection{Accessing \PropertySet Names} |
125 |
|
During mesh generation the \PropertySet objects are not identified by their name but an integer tag (mainly to provide |
126 |
|
a quicker indexing mechanism). The \TagMap which is generated by a \Design class object at mesh generation time |
127 |
|
provides an mechanism to map the property set names onto tags and vice versa. |
128 |
|
The following example illustrates the mechanis: In this case, the \TagMap \var{tm} |
129 |
|
maps the names \var{x}, \var{a} onto the tags \var{5} and \var{4} and the tag \var{4}, respectively: |
130 |
|
\begin{python} |
131 |
|
tm=TagMap({5 : "x" }) |
132 |
|
tm.setMap(a=1,x=4) |
133 |
|
print tm.getTags("a"), tm.getTags("x") |
134 |
|
\end{python} |
135 |
|
Th output is |
136 |
|
\begin{python} |
137 |
|
[ 1 ], [ 5, 4 ] |
138 |
|
\end{python} |
139 |
|
|
140 |
|
\begin{python} |
141 |
|
d=Design() |
142 |
|
d.add(PropertySet(name="a")) |
143 |
|
print d.getTagMap().getTags("a") |
144 |
|
\end{python} |
145 |
|
|
146 |
|
\begin{python} |
147 |
|
d=Design() |
148 |
|
d.add(PropertySet(name="a")) |
149 |
|
domain=esys.finley. |
150 |
|
print d.getTagMap().getTags("a") |
151 |
|
\end{python} |
152 |
|
|
153 |
|
\begin{classdesc}{TagMap}{\optional{map = \{\} }} |
154 |
|
defines a mapping between names (str) and tags (int). |
155 |
|
The dictionary \var{map} sets an initial mapping from tag to name. |
156 |
|
\end{classdesc} |
157 |
|
|
158 |
|
\begin{methoddesc}[TagMap]{setMap}{**kwargs} |
159 |
|
adds a map from names to tags using keyword arguments. For instance |
160 |
|
\var{top=1234} assigns the tag \var{123} to name \var{top}. The tag has to be integer. |
161 |
|
If a tag has been assigned to a name before the mapping will be overwritten. |
162 |
|
Notice that a single name can be assigned to different tags. |
163 |
|
\end{methoddesc} |
164 |
|
|
165 |
|
\begin{methoddesc}[TagMap]{getTags}{\optional{name=None}} |
166 |
|
returns a list of the tags assigned to \var{name}. If \var{name} is not present |
167 |
|
a list of tags is returned. |
168 |
|
\end{methoddesc} |
169 |
|
|
170 |
|
\begin{methoddesc}[TagMap]{getName}{\optional{tag=None}} |
171 |
|
returns a the name assigned to \var{name}. If \var{tag} is not present |
172 |
|
a list of all names is returned. |
173 |
|
\end{methoddesc} |
174 |
|
|
175 |
|
|
176 |
|
\begin{methoddesc}[TagMap]{getMapping}{} |
177 |
|
returns a dictionary where the tags define the keys and the values the corresponding names. |
178 |
|
\end{methoddesc} |
179 |
|
|
180 |
|
\begin{methoddesc}[TagMap]{map}{\optional{default=0}, \optional{**kwargs}} |
181 |
|
returns a dictionary where the keys are the tags and the values are the corresponding values assigned |
182 |
|
to the tag via the keyword arguments \var{**kwargs}. The value of \var{default} is used for tags |
183 |
|
which map onto name with unspecified values. |
184 |
|
|
185 |
|
The following example demonstrate the usage: |
186 |
|
\begin{python} |
187 |
|
tm=TagMap(x=5) |
188 |
|
tm.setMap(a=1,x=4,z=10) |
189 |
|
print tm.map(default = "unknown", x="john", a="peter") |
190 |
|
\end{python} |
191 |
|
The output is |
192 |
|
\begin{python} |
193 |
|
{ 5 : "john", 4: "john", 1 : "peter", 10 : "unknown" } |
194 |
|
\end{python} |
195 |
|
\end{methoddesc} |
196 |
|
|
197 |
|
\begin{methoddesc}[TagMap]{insert}{data,\optional{default=0, \optional{**kwargs}}} |
198 |
|
inserts the values assigned to name via the keyword arguments \var{**kwargs} |
199 |
|
into the \Data object \var{Data}. The value \var{default} is used for names with no given value. |
200 |
|
\end{methoddesc} |
201 |
|
|
202 |
|
\begin{methoddesc}[TagMap]{writeXML}{\optional{iostream=None}} |
203 |
|
writes an XML serialization into the \var{iostream} or if not present returns the XML representation |
204 |
|
as a string. |
205 |
|
\end{methoddesc} |
206 |
|
|
207 |
|
\begin{methoddesc}[TagMap]{fillFromXML}{iostream} |
208 |
|
uses XML data \var{iostream} defining an iostream or string. This method is the |
209 |
|
inverse method of \var{writeXML}. |
210 |
|
|
211 |
|
The following example demonstrates the usage: |
212 |
|
\begin{python} |
213 |
|
tm=TagMap(x=5) |
214 |
|
tm.setMap(a=1,x=4,z=10) |
215 |
|
tm.writeXML(open("tag_map.xml", "w")) |
216 |
|
tm2=TagMap() |
217 |
|
tm2.fillFromXML(open("tag_map.xml", "r")) |
218 |
|
\end{python} |
219 |
|
\end{methoddesc} |
220 |
|
|
221 |
|
|
222 |
|
|
223 |
|
\section{Interface to \gmshextern} |
224 |
|
\declaremodule{extension}{esys.pycad.gmsh} |
225 |
|
\modulesynopsis{Python geometry description and meshing interface} |
226 |
|
|
227 |
|
\begin{classdesc}{Design}{ |
228 |
|
\optional{dim=3, \optional{element_size=1., \optional{order=1, \optional{keep_files=False}}}}} |
229 |
|
The \class{Design} describes the geometry defined by primitives to be meshed. |
230 |
|
The \var{dim} specifies the spatial dimension. The argument \var{element_size} defines the global |
231 |
|
element size which is multiplied by the local scale to set the element size at each \Point. |
232 |
|
The argument \var{order} defines the element order to be used. If \var{keep_files} is set to |
233 |
|
\True temporary files a kept otherwise they are removed when the instance of the class is deleted. |
234 |
|
\end{classdesc} |
235 |
|
|
236 |
|
|
237 |
|
\begin{methoddesc}[Design]{setDim}{\optional{dim=3}} |
238 |
|
sets the spatial dimension which needs to be $1$, $2$ or $3$. |
239 |
|
\end{methoddesc} |
240 |
|
|
241 |
|
\begin{methoddesc}[Design]{getDim}{} |
242 |
|
returns the spatial dimension. |
243 |
|
\end{methoddesc} |
244 |
|
|
245 |
|
\begin{methoddesc}[Design]{setElementOrder}{\optional{order=1}} |
246 |
|
sets the element order which needs to be $1$ or $2$. |
247 |
|
\end{methoddesc} |
248 |
|
|
249 |
|
\begin{methoddesc}[Design]{getElementOrder}{} |
250 |
|
returns the element order. |
251 |
|
\end{methoddesc} |
252 |
|
|
253 |
|
|
254 |
|
\begin{methoddesc}[Design]{setElementSize}{\optional{element_size=1}} |
255 |
|
set the global element size. The local element size at a point is defined as |
256 |
|
the global element size multipied by the local scale. The element size must be positive. |
257 |
|
\end{methoddesc} |
258 |
|
|
259 |
|
|
260 |
|
\begin{methoddesc}[Design]{getElementSize}{} |
261 |
|
returns the global element size. |
262 |
|
\end{methoddesc} |
263 |
|
|
264 |
|
\begin{memberdesc}[Design]{DELAUNAY} |
265 |
|
the \gmshextern Delauny triangulator. |
266 |
|
\end{memberdesc} |
267 |
|
|
268 |
|
\begin{memberdesc}[Design]{TETGEN} |
269 |
|
the TetGen~\cite{TETGEN} triangulator. |
270 |
|
\end{memberdesc} |
271 |
|
|
272 |
|
\begin{memberdesc}[Design]{TETGEN} |
273 |
|
the NETGEN~\cite{NETGEN} triangulator. |
274 |
|
\end{memberdesc} |
275 |
|
|
276 |
|
\begin{methoddesc}[Design]{setKeepFilesOn}{} |
277 |
|
work files are kept at the end of the generation. |
278 |
|
\end{methoddesc} |
279 |
|
|
280 |
|
\begin{methoddesc}[Design]{setKeepFilesOff}{} |
281 |
|
work files are deleted at the end of the generation. |
282 |
|
\end{methoddesc} |
283 |
|
|
284 |
|
\begin{methoddesc}[Design]{keepFiles}{} |
285 |
|
returns \True if work files are kept. Otherwise \False is returned. |
286 |
|
\end{methoddesc} |
287 |
|
|
288 |
|
\begin{methoddesc}[Design]{setScriptFileName}{\optional{name=None}} |
289 |
|
set the filename for the \gmshextern input script. if no name is given a name with extension "geo" is generated. |
290 |
|
\end{methoddesc} |
291 |
|
|
292 |
|
\begin{methoddesc}[Design]{getScriptFileName}{} |
293 |
|
returns the name of the file for the \gmshextern script. |
294 |
|
\end{methoddesc} |
295 |
|
|
296 |
|
|
297 |
|
\begin{methoddesc}[Design]{setMeshFileName}{\optional{name=None}} |
298 |
|
sets the name for the \gmshextern mesh file. if no name is given a name with extension "msh" is generated. |
299 |
|
\end{methoddesc} |
300 |
|
|
301 |
|
\begin{methoddesc}[Design]{getMeshFileName}{} |
302 |
|
returns the name of the file for the gmsh msh |
303 |
|
\end{methoddesc} |
304 |
|
|
305 |
|
|
306 |
|
\begin{methoddesc}[Design]{addItems}{*items} |
307 |
|
adds the tuple of var{items}. An item can be any primitive or a \class{PropertySet}. |
308 |
|
\warning{If a \PropertySet is added as an item added object that are not |
309 |
|
part of a \PropertySet are not considered in the messing. |
310 |
|
} |
311 |
|
|
312 |
|
\end{methoddesc} |
313 |
|
|
314 |
|
\begin{methoddesc}[Design]{getItems}{} |
315 |
|
returns a list of the items |
316 |
|
\end{methoddesc} |
317 |
|
|
318 |
|
\begin{methoddesc}[Design]{clearItems}{} |
319 |
|
resets the items in design |
320 |
|
\end{methoddesc} |
321 |
|
|
322 |
|
\begin{methoddesc}[Design]{getMeshHandler}{} |
323 |
|
returns a handle to the mesh. The call of this method generates the mesh from the geometry and |
324 |
|
returns a mechnism to access the mesh data. In the current implementation this |
325 |
|
is this method returns a file name for a \gmshextern file containing the mesh data but this may change in |
326 |
|
later versions. |
327 |
|
\end{methoddesc} |
328 |
|
|
329 |
|
\begin{methoddesc}[Design]{getScriptString}{} |
330 |
|
returns the \gmshextern script to generate the mesh as string. |
331 |
|
\end{methoddesc} |
332 |
|
|
333 |
|
\begin{methoddesc}[Design]{getCommandString}{} |
334 |
|
returns the \gmshextern command used to generate the mesh as string.. |
335 |
|
\end{methoddesc} |
336 |
|
|
337 |
|
\begin{methoddesc}[Design]{setOptions}{\optional{algorithm=None, \optional{ optimize_quality=True,\optional{ smoothing=1}}}} |
338 |
|
sets options for the mesh generator. \var{algorithm} sets the algorithm to be used. |
339 |
|
The algorithm needs to be \var{Design.DELAUNAY} |
340 |
|
\var{Design.TETGEN} |
341 |
|
or \var{Design.NETGEN}. By default \var{Design.DELAUNAY} is used. \var{optimize_quality}=\True invokes an optimization of the mesh quality. \var{smoothing} sets the number of smoothing steps to be applied to the mesh. |
342 |
|
\end{methoddesc} |
343 |
|
|
344 |
|
\begin{methoddesc}[Design]{getTagMap}{} |
345 |
|
returns a \class{TagMap} to map the name \class{PropertySet} in the class to tag numbers generated by \gmshextern. |
346 |
|
\end{methoddesc} |