 some hint on how to access gmsh error messages added.

 1 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % 4 % Copyright (c) 2003-2009 by University of Queensland 5 % Earth Systems Science Computational Center (ESSCC) 6 7 % 8 % Primary Business: Queensland, Australia 9 % Licensed under the Open Software License version 3.0 10 11 % 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 14 15 16 \chapter{The Module \pycad} \label{PYCAD CHAP} 17 18 19 \section{Introduction} 20 21 \pycad provides a simple way to build a mesh for your finite element 22 simulation. You begin by building what we call a \class{Design} using 23 primitive geometric objects, and then to go on to build a mesh from 24 this. The final step of generating the mesh from a \class{Design} 25 uses freely available mesh generation software, such as \gmshextern. 26 27 A \class{Design} is built by defining points, which are used to specify 28 the corners of geometric objects and the vertices of curves. Using 29 points you construct more interesting objects such as lines, 30 rectangles, and arcs. By adding many of these objects into what we 31 call a \class{Design}, you can build meshes for arbitrarily complex 2-D 32 and 3-D structures. 33 34 \section{The Unit Square} 35 So the simplest geometry is the unit square. First we generate the 36 corner points 37 \begin{python} 38 from esys.pycad import * 39 p0=Point(0.,0.,0.) 40 p1=Point(1.,0.,0.) 41 p2=Point(1.,1.,0.) 42 p3=Point(0.,1.,0.) 43 \end{python} 44 which are then linked to define the edges of the square 45 \begin{python} 46 l01=Line(p0,p1) 47 l12=Line(p1,p2) 48 l23=Line(p2,p3) 49 l30=Line(p3,p0) 50 \end{python} 51 The lines are put together to form a loop 52 \begin{python} 53 c=CurveLoop(l01,l12,l23,l30) 54 \end{python} 55 The orientation of the line defining the \class{CurveLoop} is important. It is assumed that the surrounded 56 area is to the left when moving along the lines from their starting points towards the end points. Moreover, 57 the line need to form a closed loop. 58 59 We use the \class{CurveLoop} to define a surface 60 \begin{python} 61 s=PlaneSurface(c) 62 \end{python} 63 Notice there is difference between the \class{CurveLoop} defining the boundary 64 of the surface and the actually surface \class{PlaneSurface}. This difference becomes clearer in the next example with a hole. The direction of the lines is important. 65 New we are ready to define the geometry which described by an instance of \class{Design} class: 66 \begin{python} 67 d=Design(dim=2,element_size=0.05) 68 \end{python} 69 Here we use the two dimensional domain with a local element size in the finite element mesh of $0.05$. 70 We then add the surface \code{s} to the geometry 71 \begin{python} 72 d.addItems(s) 73 \end{python} 74 This will automatically import all items used to construct \code{s} into the \class{Design} \code{d}. 75 Now we are ready to construct a \finley FEM mesh and then write it to the file \file{quad.fly}: 76 \begin{python} 77 from esys.finley import MakeDomain 78 dom=MakeDomain(d) 79 dom.write("quad.fly") 80 \end{python} 81 In some cases it is useful to access the script used to generate the geometry. You can specify a specific name 82 for the script file. In our case we use 83 \begin{python} 84 d.setScriptFileName("quad.geo") 85 \end{python} 86 If we put everything together we get the script 87 \begin{python} 88 from esys.pycad import * 89 from esys.pycad.gmsh import Design 90 from esys.finley import MakeDomain 91 p0=Point(0.,0.,0.) 92 p1=Point(1.,0.,0.) 93 p2=Point(1.,1.,0.) 94 p3=Point(0.,1.,0.) 95 l01=Line(p0,p1) 96 l12=Line(p1,p2) 97 l23=Line(p2,p3) 98 l30=Line(p3,p0) 99 c=CurveLoop(l01,l12,l23,l30) 100 s=PlaneSurface(c) 101 d=Design(dim=2,element_size=0.05) 102 d.setScriptFileName("quad.geo") 103 d.setMeshFileName("quad.msh") 104 d.addItems(s) 105 pl1=PropertySet("sides",l01,l23) 106 pl2=PropertySet("top_and_bottom",l12,l30) 107 d.addItems(pl1, pl2) 108 dom=MakeDomain(d) 109 dom.write("quad.fly") 110 \end{python} 111 This example is included with the software in 112 \file{quad.py} in the \ExampleDirectory. 113 114 There are three extra statements which we have not discussed yet: By default the mesh used to subdivide 115 the boundary are not written into the mesh file mainly to reduce the size of the data file. One need to explicitly add the lines to the \Design which should be present in the mesh data. Here we additionally labeled the 116 lines on the top and the bottom with the name top_and_bottom and the lines on the left and right hand side 117 with the name sides using \class{PropertySet} objects. The labeling is convenient 118 when using tagging \index{tagging}, see Chapter~\ref{ESCRIPT CHAP}. 119 120 \begin{figure} 121 \centerline{\includegraphics[width=\figwidth]{figures/quad.eps}} 122 \caption{Trapozid with triangle Hole.} 123 \label{fig:PYCAD 0} 124 \end{figure} 125 126 If you have \gmshextern installed you can run the example and view the geometry and mesh with: 127 \begin{python} 128 escript quad.py 129 gmsh quad.geo 130 gmsh quad.msh 131 \end{python} 132 You can access error messages from \gmshextern in the \file{.gmsh-errors} in your home directory. 133 See Figure~\ref{fig:PYCAD 0} for a result. 134 135 In most cases it is best practice to generate the mesh and to solve the mathematical 136 model in to different scripts. In our example you can read the \finley mesh into your simulation 137 code\footnote{\gmshextern files can be directly read using the \function{ReadGmsh}, see Chapter~\ref{CHAPTER ON FINLEY}} using 138 \begin{python} 139 from finley import ReadMesh 140 mesh=ReadMesh("quad.fly") 141 \end{python} 142 Note that the underlying mesh generation software will not accept all 143 the geometries you can create with \pycad. For example, \pycad 144 will happily allow you to create a 2-D \class{Design} that is a 145 closed loop with some additional points or lines lying outside of the 146 enclosed area, but \gmshextern will fail to create a mesh for it. 147 148 \begin{figure} 149 \centerline{\includegraphics[width=\figwidth]{figures/trap.eps}} 150 \caption{Trapozid with triangle Hole.} 151 \label{fig:PYCAD 1} 152 \end{figure} 153 154 155 \section{Holes} 156 The example included below shows how to use \pycad to create a 2-D mesh 157 in the shape of a trapezoid with a cut-out area, see Figure~\ref{fig:PYCAD 1}: 158 \begin{python} 159 from esys.pycad import * 160 from esys.pycad.gmsh import Design 161 from esys.finley import MakeDomain 162 163 # A trapezoid 164 p0=Point(0.0, 0.0, 0.0) 165 p1=Point(1.0, 0.0, 0.0) 166 p2=Point(1.0, 0.5, 0.0) 167 p3=Point(0.0, 1.0, 0.0) 168 l01=Line(p0, p1) 169 l12=Line(p1, p2) 170 l23=Line(p2, p3) 171 l30=Line(p3, p0) 172 c=CurveLoop(l01, l12, l23, l30) 173 174 # A small triangular cutout 175 x0=Point(0.1, 0.1, 0.0) 176 x1=Point(0.5, 0.1, 0.0) 177 x2=Point(0.5, 0.2, 0.0) 178 x01=Line(x0, x1) 179 x12=Line(x1, x2) 180 x20=Line(x2, x0) 181 cutout=CurveLoop(x01, x12, x20) 182 183 # Create the surface with cutout 184 s=PlaneSurface(c, holes=[cutout]) 185 186 # Create a Design which can make the mesh 187 d=Design(dim=2, element_size=0.05) 188 189 # Add the trapezoid with cutout 190 d.addItems(s) 191 192 # Create the geometry, mesh and Escript domain 193 d.setScriptFileName("trapezoid.geo") 194 d.setMeshFileName("trapezoid.msh") 195 domain=MakeDomain(d) 196 # write mesh to a finley file: 197 domain.write("trapezoid.fly") 198 \end{python} 199 This example is included with the software in 200 \file{trapezoid.py} in the \ExampleDirectory. 201 202 A \code{CurveLoop} is used to connect several lines into a single curve. 203 It is used in the example above to create the trapezoidal outline for the grid 204 and also for the triangular cutout area. 205 You can use any number of lines when creating a \class{CurveLoop}, but 206 the end of one line must be identical to the start of the next. 207 208 209 \begin{figure} 210 \centerline{\includegraphics[width=\figwidth]{figures/brick.eps}} 211 \caption{Three dimensional Block.} 212 \label{fig:PYCAD 2} 213 \end{figure} 214 215 \section{A 3D example} 216 In this section we discuss the definition of 3D geometries. The example is the unit cube, see Figure~\ref{fig:PYCAD 2}. First we generate the vertices of the cube: 217 \begin{python} 218 from esys.pycad import * 219 p0=Point(0.,0.,0.) 220 p1=Point(1.,0.,0.) 221 p2=Point(0.,1.,0.) 222 p3=Point(1.,1.,0.) 223 p4=Point(0.,0.,1.) 224 p5=Point(1.,0.,1.) 225 p6=Point(0.,1.,1.) 226 p7=Point(1.,1.,1.) 227 \end{python} 228 We connect the points to form the bottom and top surfaces of the cube: 229 \begin{python} 230 l01=Line(p0,p1) 231 l13=Line(p1,p3) 232 l32=Line(p3,p2) 233 l20=Line(p2,p0) 234 bottom=PlaneSurface(CurveLoop(l01,l13,l32,l20)) 235 \end{python} 236 and 237 \begin{python} 238 l45=Line(p4,p5) 239 l57=Line(p5,p7) 240 l76=Line(p7,p6) 241 l64=Line(p6,p4) 242 top=PlaneSurface(CurveLoop(l45,l57,l76,l64)) 243 \end{python} 244 To form the front face we introduce the two additional lines connecting the left and right front 245 points of the the \code{top} and \code{bottom} face: 246 \begin{python} 247 l15=Line(p1,p5) 248 l40=Line(p4,p0) 249 \end{python} 250 To form the front face we encounter the problem as the line \code{l45} used to define the 251 \code{top} face is pointing the wrong direction. In \pycad you can reversing direction of an 252 object by changing its sign. So we write \code{-l45} to indicate that the direction is to be reversed. With this notation we can write 253 \begin{python} 254 front=PlaneSurface(CurveLoop(l01,l15,-l45,l40)) 255 \end{python} 256 Keep in mind that if you use \code{Line(p4,p5)} instead \code{-l45} both objects are treated as different although the connecting the same points with a straight line in the same direction. The resulting geometry would include an opening along the \code{p4}--\code{p5} connection. This will lead to an inconsistent mesh and may result in a failure of the volumetric mesh generator. Similarly we can define the other sides of the cube: 257 \begin{python} 258 l37=Line(p3,p7) 259 l62=Line(p6,p2) 260 back=PlaneSurface(CurveLoop(l32,-l62,-l76,-l37)) 261 left=PlaneSurface(CurveLoop(-l40,-l64,l62,l20)) 262 right=PlaneSurface(CurveLoop(-l15,l13,l37,-l57)) 263 \end{python} 264 We can now put the six surfaces together to form a \class{SurfaceLoop} defining the 265 boundary of the volume of the cube: 266 \begin{python} 267 sl=SurfaceLoop(top,-bottom,front,back,left,right) 268 v=Volume(sl) 269 \end{python} 270 Similar to the definition of a \code{CurvedLoop} the orientation of the surfaces \code{SurfaceLoop} is relevant. In fact the surface normal direction defined by the the right hand rule needs to point outwards as indicated by the surface normals in 271 Figure~\ref{fig:PYCAD 2}. As the \code{bottom} face is directed upwards it is inserted with the minus sign 272 into the \code{SurfaceLoop} in order to adjust the orientation of the surface. 273 274 As in the 2D case, the \class{Design} class is used to define the geometry: 275 \begin{python} 276 from esys.pycad.gmsh import Design 277 from esys.finley import MakeDomain 278 279 des=Design(dim=3, element_size = 0.1, keep_files=True) 280 des.setScriptFileName("brick.geo") 281 des.addItems(v, top, bottom, back, front, left , right) 282 283 dom=MakeDomain(des) 284 dom.write("brick.fly") 285 \end{python} 286 Note that the \finley mesh file \file{brick.fly} will contain the 287 triangles used to define the surfaces as they are added to the \class{Design}. 288 The example script of the cube is included with the software in 289 \file{brick.py} in the \ExampleDirectory. 290 291 \begin{figure} 292 \centerline{\includegraphics[width=\figwidth]{figures/refine1.eps}} 293 \caption{Local refinement at the origin by 294 \var{local_scale=0.01} 295 with \var{element_size=0.3} and number of elements on the top set to 10.} 296 \label{fig:PYCAD 5} 297 \end{figure} 298 299 \section{Element Sizes} 300 The element size used globally is defined by the 301 \code{element_size} argument of the \class{Design}. The mesh generator 302 will try to use this mesh size everywhere in the geometry. In some cases it can be 303 desirable to use locally a finer mesh. A local refinement can be defined at each 304 \class{Point}: 305 \begin{python} 306 p0=Point(0.,0.,0.,local_scale=0.01) 307 \end{python} 308 Here the mesh generator will create a mesh with an element size which is by the factor \code{0.01} 309 times smaller than the global mesh size \code{element_size=0.3}, see Figure~\ref{fig:PYCAD 5}. The point where a refinement is defined must be a point of curve used to define the geometry. 310 311 Alternatively, one can define a mesh size along a curve by defining the number of elements to be used to subdivide the curve. For instance, to use $20$ element on line \code{l23} on uses: 312 \begin{python} 313 l23=Line(p2, p3) 314 l23.setElementDistribution(20) 315 \end{python} 316 Setting the number of elements on a curve overwrites the global mesh size \code{element_size}. The result is shown in Figure~\ref{fig:PYCAD 5}. 317 318 319 320 \section{\pycad Classes} 321 \declaremodule{extension}{esys.pycad} 322 \modulesynopsis{Python geometry description and meshing interface} 323 324 \subsection{Primitives} 325 326 Some of the most commonly-used objects in \pycad are listed here. For a more complete 327 list see the full API documentation. 328 329 \begin{classdesc}{Point}{x=0.,y=0.,z=0.\optional{,local_scale=1.}} 330 Create a point with from coordinates with local characteristic length \var{local_scale} 331 \end{classdesc} 332 333 \begin{classdesc}{Line}{point1, point2} 334 Create a line with between starting and ending points. 335 \end{classdesc} 336 \begin{methoddesc}[Line]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 337 Defines the number of elements on the line. If set it overwrites the local length setting which would be applied. The progression factor \var{progression} defines the change of element size between neighboured elements. If \var{createBump} is set 338 progression is applied towards the centre of the line. 339 \end{methoddesc} 340 \begin{methoddesc}[Line]{resetElementDistribution}{} 341 removes a previously set element distribution from the line. 342 \end{methoddesc} 343 \begin{methoddesc}[Line]{getElemenofDistribution}{} 344 Returns the element distribution as tuple of 345 number of elements, progression factor and bump flag. If 346 no element distribution is set None is returned. 347 \end{methoddesc} 348 349 350 \begin{classdesc}{Spline}{point0, point1, ...} 351 A spline curve defined by a list of points \var{point0}, \var{point1},.... 352 \end{classdesc} 353 \begin{methoddesc}[Spline]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 354 Defines the number of elements on the line. If set it overwrites the local length setting which would be applied. The progression factor \var{progression} defines the change of element size between neighboured elements. If \var{createBump} is set 355 progression is applied towards the centre of the line. 356 \end{methoddesc} 357 \begin{methoddesc}[Spline]{resetElementDistribution}{} 358 removes a previously set element distribution from the line. 359 \end{methoddesc} 360 \begin{methoddesc}[Spline]{getElemenofDistribution}{} 361 Returns the element distribution as tuple of 362 number of elements, progression factor and bump flag. If 363 no element distribution is set None is returned. 364 \end{methoddesc} 365 366 \begin{classdesc}{BSpline}{point0, point1, ...} 367 A B-spline curve defined by a list of points \var{point0}, \var{point1},.... 368 \end{classdesc} 369 \begin{methoddesc}[BSpline]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 370 Defines the number of elements on the line. If set it overwrites the local length setting which would be applied. The progression factor \var{progression} defines the change of element size between neighboured elements. If \var{createBump} is set 371 progression is applied towards the centre of the line. 372 \end{methoddesc} 373 \begin{methoddesc}[BSpline]{resetElementDistribution}{} 374 removes a previously set element distribution from the line. 375 \end{methoddesc} 376 \begin{methoddesc}[BSpline]{getElemenofDistribution}{} 377 Returns the element distribution as tuple of 378 number of elements, progression factor and bump flag. If 379 no element distribution is set None is returned. 380 \end{methoddesc} 381 382 \begin{classdesc}{BezierCurve}{point0, point1, ...} 383 A Brezier spline curve defined by a list of points \var{point0}, \var{point1},.... 384 \end{classdesc} 385 \begin{methoddesc}[BezierCurve]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 386 Defines the number of elements on the line. If set it overwrites the local length setting which would be applied. The progression factor \var{progression} defines the change of element size between neighboured elements. If \var{createBump} is set 387 progression is applied towards the centre of the line. 388 \end{methoddesc} 389 \begin{methoddesc}[BezierCurve]{resetElementDistribution}{} 390 removes a previously set element distribution from the line. 391 \end{methoddesc} 392 \begin{methoddesc}[BezierCurve]{getElemenofDistribution}{} 393 Returns the element distribution as tuple of 394 number of elements, progression factor and bump flag. If 395 no element distribution is set None is returned. 396 \end{methoddesc} 397 398 \begin{classdesc}{Arc}{centre_point, start_point, end_point} 399 Create an arc by specifying a centre for a circle and start and end points. An arc may subtend an angle of at most $\pi$ radians. 400 \end{classdesc} 401 \begin{methoddesc}[Arc]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 402 Defines the number of elements on the line. If set it overwrites the local length setting which would be applied. The progression factor \var{progression} defines the change of element size between neighboured elements. If \var{createBump} is set 403 progression is applied towards the centre of the line. 404 \end{methoddesc} 405 \begin{methoddesc}[Arc]{resetElementDistribution}{} 406 removes a previously set element distribution from the line. 407 \end{methoddesc} 408 \begin{methoddesc}[Arc]{getElemenofDistribution}{} 409 Returns the element distribution as tuple of 410 number of elements, progression factor and bump flag. If 411 no element distribution is set None is returned. 412 \end{methoddesc} 413 414 \begin{classdesc}{CurveLoop}{list} 415 Create a closed curve from the \code{list}. of 416 \class{Line}, \class{Arc}, \class{Spline}, \class{BSpline}, 417 \class{BrezierSpline}. 418 \end{classdesc} 419 420 \begin{classdesc}{PlaneSurface}{loop, \optional{holes=[list]}} 421 Create a plane surface from a \class{CurveLoop}, which may have one or more holes 422 described by \var{list} of \class{CurveLoop}. 423 \end{classdesc} 424 \begin{methoddesc}[PlaneSurface]{setRecombination}{max_deviation} 425 the mesh generator will try to recombine triangular elements 426 into quadrilateral elements. \var{max_deviation} (in radians) defines the 427 maximum deviation of any angle in the quadrilaterals from the right angle. 428 Set \var{max_deviation}=\var{None} to remove recombination. 429 \end{methoddesc} 430 \begin{methoddesc}[PlaneSurface]{setTransfiniteMeshing}{\optional{orientation="Left"}} 431 applies 2D transfinite meshing to the surface. 432 \var{orientation} defines the orientation of triangles. Allowed values 433 are \var{Left''}, \var{Right''} or \var{Alternate''}. The 434 boundary of the surface must be defined by three or four lines where an 435 element distribution must be defined on all faces where opposite 436 faces uses the same element distribution. No holes must be present. 437 \end{methoddesc} 438 439 440 441 \begin{classdesc}{RuledSurface}{list} 442 Create a surface that can be interpolated using transfinite interpolation. 443 \var{list} gives a list of three or four lines defining the boundary of the 444 surface. 445 \end{classdesc} 446 \begin{methoddesc}[RuledSurface]{setRecombination}{max_deviation} 447 the mesh generator will try to recombine triangular elements 448 into quadrilateral elements. \var{max_deviation} (in radians) defines the 449 maximum deviation of any angle in the quadrilaterals from the right angle. 450 Set \var{max_deviation}=\var{None} to remove recombination. 451 \end{methoddesc} 452 \begin{methoddesc}[RuledSurface]{setTransfiniteMeshing}{\optional{orientation="Left"}} 453 applies 2D transfinite meshing to the surface. 454 \var{orientation} defines the orientation of triangles. Allowed values 455 are \var{Left''}, \var{Right''} or \var{Alternate''}. The 456 boundary of the surface must be defined by three or four lines where an 457 element distribution must be defined on all faces where opposite 458 faces uses the same element distribution. No holes must be present. 459 \end{methoddesc} 460 461 462 \begin{classdesc}{SurfaceLoop}{list} 463 Create a loop of \class{PlaneSurface} or \class{RuledSurface}, which defines the shell of a volume. 464 \end{classdesc} 465 466 \begin{classdesc}{Volume}{loop, \optional{holes=[list]}} 467 Create a volume given a \class{SurfaceLoop}, which may have one or more holes 468 define by the list of \class{SurfaceLoop}. 469 \end{classdesc} 470 471 \begin{classdesc}{PropertySet}{list} 472 Create a PropertySet given a list of 1-D, 2-D or 3-D items. See the section on Properties below for more information. 473 \end{classdesc} 474 475 %============================================================================================================ 476 \subsection{Transformations} 477 478 Sometimes it's convenient to create an object and then make copies at 479 different orientations and in different sizes. Transformations are 480 used to move geometrical objects in the 3-dimensional space and to 481 resize them. 482 483 \begin{classdesc}{Translation}{\optional{b=[0,0,0]}} 484 defines a translation $x \to x+b$. \var{b} can be any object that can be converted 485 into a \numpy object of shape $(3,)$. 486 \end{classdesc} 487 488 \begin{classdesc}{Rotatation}{\optional{axis=[1,1,1], \optional{ point = [0,0,0], \optional{angle=0*RAD} } } } 489 defines a rotation by \var{angle} around axis through point \var{point} and direction \var{axis}. 490 \var{axis} and \var{point} can be any object that can be converted 491 into a \numpy object of shape $(3,)$. 492 \var{axis} does not have to be normalised but must have positive length. The right hand rule~\cite{RIGHTHANDRULE} 493 applies. 494 \end{classdesc} 495 496 497 \begin{classdesc}{Dilation}{\optional{factor=1., \optional{centre=[0,0,0]}}} 498 defines a dilation by the expansion/contraction \var{factor} with 499 \var{centre} as the dilation centre. 500 \var{centre} can be any object that can be converted 501 into a \numpy object of shape $(3,)$. 502 \end{classdesc} 503 504 \begin{classdesc}{Reflection}{\optional{normal=[1,1,1], \optional{offset=0}}} 505 defines a reflection on a plane defined in normal form $n^t x = d$ 506 where $n$ is the surface normal \var{normal} and $d$ is the plane \var{offset}. 507 \var{normal} can be any object that can be converted 508 into a \numpy object of shape $(3,)$. 509 \var{normal} does not have to be normalised but must have positive length. 510 \end{classdesc} 511 512 \begin{datadesc}{DEG} 513 A constant to convert from degrees to an internal angle representation in radians. For instance use \code{90*DEG} for $90$ degrees. 514 \end{datadesc} 515 516 \subsection{Properties} 517 518 If you are building a larger geometry you may find it convenient to 519 create it in smaller pieces and then assemble them into the whole. 520 Property sets make this easy, and they allow you to name the smaller 521 pieces for convenience. 522 523 Property sets are used to bundle a set of geometrical objects in a 524 group. The group is identified by a name. Typically a property set 525 is used to mark subregions with share the same material properties or 526 to mark portions of the boundary. For efficiency, the \Design class 527 object assigns a integer to each of its property sets, a so-called tag 528 \index{tag}. The appropriate tag is attached to the elements at 529 generation time. 530 531 See the file \code{pycad/examples/quad.py} for an example using a {\it PropertySet}. 532 533 534 \begin{classdesc}{PropertySet}{name,*items} 535 defines a group geometrical objects which can be accessed through a \var{name} 536 The objects in the tuple \var{items} mast all be \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD objects. 537 \end{classdesc} 538 539 540 \begin{methoddesc}[PropertySet]{getManifoldClass}{} 541 returns the manifold class \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD expected from the items 542 in the property set. 543 \end{methoddesc} 544 545 \begin{methoddesc}[PropertySet]{getDim}{} 546 returns the spatial dimension of the items 547 in the property set. 548 \end{methoddesc} 549 550 \begin{methoddesc}[PropertySet]{getName}{} 551 returns the name of the set 552 \end{methoddesc} 553 554 \begin{methoddesc}[PropertySet]{setName}{name} 555 sets the name. This name should be unique within a \Design. 556 \end{methoddesc} 557 558 \begin{methoddesc}[PropertySet]{addItem}{*items} 559 adds a tuple of items. They need to be objects of class \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD. 560 \end{methoddesc} 561 562 \begin{methoddesc}[PropertySet]{getItems}{} 563 returns the list of items 564 \end{methoddesc} 565 566 \begin{methoddesc}[PropertySet]{clearItems}{} 567 clears the list of items 568 \end{methoddesc} 569 570 \begin{methoddesc}[PropertySet]{getTag}{} 571 returns the tag used for this property set 572 \end{methoddesc} 573 574 \section{Interface to the mesh generation software} 575 \declaremodule{extension}{esys.pycad.gmsh} 576 \modulesynopsis{Python geometry description and meshing interface} 577 578 The class and methods described here provide an interface to the mesh 579 generation software, which is currently \gmshextern. This interface could be 580 adopted to triangle or another mesh generation package if this is 581 deemed to be desirable in the future. 582 583 \begin{classdesc}{Design}{ 584 \optional{dim=3, \optional{element_size=1., \optional{order=1, \optional{keep_files=False}}}}} 585 The \class{Design} describes the geometry defined by primitives to be meshed. 586 The \var{dim} specifies the spatial dimension. The argument \var{element_size} defines the global 587 element size which is multiplied by the local scale to set the element size at each \Point. 588 The argument \var{order} defines the element order to be used. If \var{keep_files} is set to 589 \True temporary files a kept otherwise they are removed when the instance of the class is deleted. 590 \end{classdesc} 591 592 593 \begin{methoddesc}[Design]{setDim}{\optional{dim=3}} 594 sets the spatial dimension which needs to be $1$, $2$ or $3$. 595 \end{methoddesc} 596 597 \begin{methoddesc}[Design]{getDim}{} 598 returns the spatial dimension. 599 \end{methoddesc} 600 601 \begin{methoddesc}[Design]{setElementOrder}{\optional{order=1}} 602 sets the element order which needs to be $1$ or $2$. 603 \end{methoddesc} 604 605 \begin{methoddesc}[Design]{getElementOrder}{} 606 returns the element order. 607 \end{methoddesc} 608 609 610 \begin{methoddesc}[Design]{setElementSize}{\optional{element_size=1}} 611 set the global element size. The local element size at a point is defined as 612 the global element size multiplied by the local scale. The element size must be positive. 613 \end{methoddesc} 614 615 616 \begin{methoddesc}[Design]{getElementSize}{} 617 returns the global element size. 618 \end{methoddesc} 619 620 \begin{memberdesc}[Design]{DELAUNAY} 621 the gmsh Delauny triangulator. 622 \end{memberdesc} 623 624 \begin{memberdesc}[Design]{TETGEN} 625 the TetGen~\cite{TETGEN} triangulator. 626 \end{memberdesc} 627 628 \begin{memberdesc}[Design]{NETGEN} 629 the NETGEN~\cite{NETGEN} triangulator. 630 \end{memberdesc} 631 632 \begin{methoddesc}[Design]{setKeepFilesOn}{} 633 work files are kept at the end of the generation. 634 \end{methoddesc} 635 636 \begin{methoddesc}[Design]{setKeepFilesOff}{} 637 work files are deleted at the end of the generation. 638 \end{methoddesc} 639 640 \begin{methoddesc}[Design]{keepFiles}{} 641 returns \True if work files are kept. Otherwise \False is returned. 642 \end{methoddesc} 643 644 \begin{methoddesc}[Design]{setScriptFileName}{\optional{name=None}} 645 set the file name for the gmsh input script. if no name is given a name with extension "geo" is generated. 646 \end{methoddesc} 647 648 \begin{methoddesc}[Design]{getScriptFileName}{} 649 returns the name of the file for the gmsh script. 650 \end{methoddesc} 651 652 653 \begin{methoddesc}[Design]{setMeshFileName}{\optional{name=None}} 654 sets the name for the gmsh mesh file. if no name is given a name with extension "msh" is generated. 655 \end{methoddesc} 656 657 \begin{methoddesc}[Design]{getMeshFileName}{} 658 returns the name of the file for the gmsh msh 659 \end{methoddesc} 660 661 662 \begin{methoddesc}[Design]{addItems}{*items} 663 adds the tuple of var{items}. An item can be any primitive or a \class{PropertySet}. 664 \warning{If a \PropertySet is added as an item added object that are not 665 part of a \PropertySet are not considered in the messing. 666 } 667 668 \end{methoddesc} 669 670 \begin{methoddesc}[Design]{getItems}{} 671 returns a list of the items 672 \end{methoddesc} 673 674 \begin{methoddesc}[Design]{clearItems}{} 675 resets the items in design 676 \end{methoddesc} 677 678 \begin{methoddesc}[Design]{getMeshHandler}{} 679 returns a handle to the mesh. The call of this method generates the mesh from the geometry and 680 returns a mechanism to access the mesh data. In the current implementation this 681 method returns a file name for a gmsh file containing the mesh data. 682 \end{methoddesc} 683 684 \begin{methoddesc}[Design]{getScriptString}{} 685 returns the gmsh script to generate the mesh as a string. 686 \end{methoddesc} 687 688 \begin{methoddesc}[Design]{getCommandString}{} 689 returns the gmsh command used to generate the mesh as string. 690 \end{methoddesc} 691 692 \begin{methoddesc}[Design]{setOptions}{\optional{algorithm=None, \optional{ optimize_quality=True,\optional{ smoothing=1}}}} 693 sets options for the mesh generator. \var{algorithm} sets the algorithm to be used. 694 The algorithm needs to be \var{Design.DELAUNAY} 695 \var{Design.TETGEN} 696 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. 697 \end{methoddesc} 698 699 \begin{methoddesc}[Design]{getTagMap}{} 700 returns a \class{TagMap} to map the name \class{PropertySet} in the class to tag numbers generated by gmsh. 701 \end{methoddesc}