1 ksteube 1811 2 jfenwick 3989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 jfenwick 6651 % Copyright (c) 2003-2018 by The University of Queensland 4 jfenwick 3989 5 ksteube 1811 % 6 % Primary Business: Queensland, Australia 7 jfenwick 6112 % Licensed under the Apache License, version 2.0 8 9 ksteube 1811 % 10 jfenwick 3989 % Development until 2012 by Earth Systems Science Computational Center (ESSCC) 11 jfenwick 4657 % Development 2012-2013 by School of Earth Sciences 12 % Development from 2014 by Centre for Geoscience Computing (GeoComp) 13 jfenwick 3989 % 14 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 15 ksteube 1811 16 caltinay 3293 \chapter{The \pycad Module}\label{PYCAD CHAP} 17 ksteube 1811 18 gross 999 \section{Introduction} 19 20 ksteube 1066 \pycad provides a simple way to build a mesh for your finite element 21 caltinay 3324 simulation. You begin by building what we call a \class{Design} using 22 primitive geometric objects, and then go on to build a mesh from this. 23 The final step of generating the mesh from a \class{Design} uses freely 24 available mesh generation software, such as \gmshextern. 25 gross 999 26 gross 2683 A \class{Design} is built by defining points, which are used to specify 27 caltinay 3324 the corners of geometric objects and the vertices of curves. Using 28 ksteube 1066 points you construct more interesting objects such as lines, 29 caltinay 3324 rectangles, and arcs. By adding many of these objects into a \class{Design}, 30 you can build meshes for arbitrarily complex 2-D and 3-D structures. 31 ksteube 1066 32 gross 2683 \section{The Unit Square} 33 caltinay 3324 The simplest geometry is the unit square. First we generate the corner points 34 gross 2683 \begin{python} 35 caltinay 3324 from esys.pycad import * 36 p0=Point(0.,0.,0.) 37 p1=Point(1.,0.,0.) 38 p2=Point(1.,1.,0.) 39 p3=Point(0.,1.,0.) 40 gross 2683 \end{python} 41 which are then linked to define the edges of the square 42 \begin{python} 43 caltinay 3324 l01=Line(p0,p1) 44 l12=Line(p1,p2) 45 l23=Line(p2,p3) 46 l30=Line(p3,p0) 47 gross 2683 \end{python} 48 caltinay 3293 The lines are put together to form a loop 49 gross 2683 \begin{python} 50 caltinay 3324 c=CurveLoop(l01,l12,l23,l30) 51 gross 2683 \end{python} 52 caltinay 3324 The orientation of the line defining the \class{CurveLoop} is important. 53 It is assumed that the surrounded area is to the left when moving along the 54 lines from their starting points towards the end points. 55 Moreover, the line needs to form a closed loop. 56 We now use the \class{CurveLoop} to define a surface 57 ksteube 1066 \begin{python} 58 caltinay 3324 s=PlaneSurface(c) 59 gross 2683 \end{python} 60 caltinay 3324 Note that there is a difference between the \class{CurveLoop}, which defines 61 the boundary of the surface, and the actual surface \class{PlaneSurface}. 62 This difference becomes clearer in the next example with a hole. 63 Now we are ready to define the geometry which is described by an instance of 64 the \class{Design} class: 65 gross 2683 \begin{python} 66 caltinay 3324 d=Design(dim=2,element_size=0.05) 67 gross 2683 \end{python} 68 caltinay 3324 Here we use the two-dimensional domain with a local element size in the finite 69 element mesh of $0.05$. 70 gross 2683 We then add the surface \code{s} to the geometry 71 \begin{python} 72 caltinay 3324 d.addItems(s) 73 gross 2683 \end{python} 74 caltinay 3324 This will automatically import all items used to construct \code{s} into the 75 \class{Design} \code{d}. 76 Now we are ready to construct a \finley FEM mesh and then write it to the file 77 \file{quad.fly}: 78 gross 2683 \begin{python} 79 caltinay 3324 from esys.finley import MakeDomain 80 dom=MakeDomain(d) 81 dom.write("quad.fly") 82 gross 2683 \end{python} 83 caltinay 3324 In some cases it is useful to access the script used to generate the geometry. 84 You can specify a specific name for the script file. In our case we use 85 gross 2683 \begin{python} 86 caltinay 3324 d.setScriptFileName("quad.geo") 87 gross 2683 \end{python} 88 caltinay 3324 It is also useful to check error messages generated during the mesh generation 89 process. \gmshextern writes messages to the file \file{.gmsh-errors} in your 90 home directory. 91 Putting everything together we get the script 92 gross 2683 \begin{python} 93 caltinay 3324 from esys.pycad import * 94 from esys.pycad.gmsh import Design 95 from esys.finley import MakeDomain 96 p0=Point(0.,0.,0.) 97 p1=Point(1.,0.,0.) 98 p2=Point(1.,1.,0.) 99 p3=Point(0.,1.,0.) 100 l01=Line(p0,p1) 101 l12=Line(p1,p2) 102 l23=Line(p2,p3) 103 l30=Line(p3,p0) 104 c=CurveLoop(l01,l12,l23,l30) 105 s=PlaneSurface(c) 106 d=Design(dim=2,element_size=0.05) 107 d.setScriptFileName("quad.geo") 108 d.addItems(s) 109 pl1=PropertySet("sides",l01,l23) 110 pl2=PropertySet("top_and_bottom",l12,l30) 111 d.addItems(pl1, pl2) 112 dom=MakeDomain(d) 113 dom.write("quad.fly") 114 gross 2683 \end{python} 115 caltinay 3324 This example is included with the software in \file{quad.py} in the 116 \ExampleDirectory. 117 ksteube 1066 118 caltinay 3324 There are three extra statements which we have not discussed yet. 119 By default the mesh used to subdivide the boundary is not written into the 120 mesh file mainly to reduce the size of the data file. 121 One needs to explicitly add the lines to the \Design which should be present 122 in the mesh data. Here we additionally labeled the lines on the top and the 123 bottom with the name top_and_bottom and the lines on the left and right 124 hand side with the name sides using \class{PropertySet} objects. 125 The labeling is convenient when using tagging\index{tagging}, see \Chap{ESCRIPT CHAP}. 126 ksteube 1066 127 gross 2683 \begin{figure} 128 caltinay 3324 \centerline{\includegraphics{quad}} 129 \caption{Quadrilateral with mesh of triangles} 130 gross 2683 \label{fig:PYCAD 0} 131 \end{figure} 132 ksteube 1066 133 caltinay 3324 If you have \gmshextern installed you can run the example and view the 134 geometry and mesh with: 135 \begin{verbatim} 136 jfenwick 2923 run-escript quad.py 137 gross 2683 gmsh quad.geo 138 gmsh quad.msh 139 caltinay 3324 \end{verbatim} 140 gross 2683 See Figure~\ref{fig:PYCAD 0} for a result. 141 ksteube 1066 142 caltinay 3324 In most cases it is best practice to generate the mesh and solve the 143 mathematical model in two separate scripts. In our example you can read the 144 \finley mesh into your simulation code\footnote{\gmshextern files can be 145 caltinay 5295 directly read using \function{ReadGmsh}, see \Chap{chap:finley}} using 146 gross 2683 \begin{python} 147 caltinay 3324 from finley import ReadMesh 148 mesh=ReadMesh("quad.fly") 149 gross 2683 \end{python} 150 Note that the underlying mesh generation software will not accept all 151 caltinay 3324 the geometries you can create. For example, \pycad will happily allow 152 you to create a 2-D \class{Design} that is a closed loop with some 153 additional points or lines lying outside of the enclosed area, but 154 \gmshextern will fail to create a mesh for it. 155 ksteube 1066 156 gross 2683 \section{Holes} 157 The example included below shows how to use \pycad to create a 2-D mesh 158 caltinay 3324 in the shape of a trapezoid with a cut-out area as in Figure~\ref{fig:PYCAD 1}. 159 160 gross 2683 \begin{python} 161 caltinay 3324 from esys.pycad import * 162 from esys.pycad.gmsh import Design 163 from esys.finley import MakeDomain 164 165 # A trapezoid 166 p0=Point(0.0, 0.0, 0.0) 167 p1=Point(1.0, 0.0, 0.0) 168 p2=Point(1.0, 0.5, 0.0) 169 p3=Point(0.0, 1.0, 0.0) 170 l01=Line(p0, p1) 171 l12=Line(p1, p2) 172 l23=Line(p2, p3) 173 l30=Line(p3, p0) 174 c=CurveLoop(l01, l12, l23, l30) 175 176 # A small triangular cutout 177 x0=Point(0.1, 0.1, 0.0) 178 x1=Point(0.5, 0.1, 0.0) 179 x2=Point(0.5, 0.2, 0.0) 180 x01=Line(x0, x1) 181 x12=Line(x1, x2) 182 x20=Line(x2, x0) 183 cutout=CurveLoop(x01, x12, x20) 184 185 # Create the surface with cutout 186 s=PlaneSurface(c, holes=[cutout]) 187 188 # Create a Design which can make the mesh 189 d=Design(dim=2, element_size=0.05) 190 191 # Add the trapezoid with cutout 192 d.addItems(s) 193 194 # Create the geometry, mesh and Escript domain 195 d.setScriptFileName("trapezoid.geo") 196 d.setMeshFileName("trapezoid.msh") 197 domain=MakeDomain(d) 198 # write mesh to a finley file: 199 domain.write("trapezoid.fly") 200 \end{python} 201 This example is included with the software in \file{trapezoid.py} in the 202 \ExampleDirectory. 203 ksteube 1066 204 caltinay 3324 \begin{figure} 205 \centerline{\includegraphics{trapezoid}} 206 \caption{Trapezoid with triangular hole} 207 \label{fig:PYCAD 1} 208 \end{figure} 209 gross 2683 210 ksteube 1066 A \code{CurveLoop} is used to connect several lines into a single curve. 211 It is used in the example above to create the trapezoidal outline for the grid 212 and also for the triangular cutout area. 213 caltinay 3324 You can define any number of lines when creating a \class{CurveLoop}, but 214 ksteube 1066 the end of one line must be identical to the start of the next. 215 216 caltinay 3324 \section{A 3D example} 217 ksteube 1066 218 caltinay 3324 In this section we discuss the definition of 3D geometries. As an example 219 consider the unit cube as shown in Figure~\ref{fig:PYCAD 2}. 220 First we generate the vertices of the cube: 221 gross 2683 \begin{python} 222 caltinay 3324 from esys.pycad import * 223 p0=Point(0.,0.,0.) 224 p1=Point(1.,0.,0.) 225 p2=Point(0.,1.,0.) 226 p3=Point(1.,1.,0.) 227 p4=Point(0.,0.,1.) 228 p5=Point(1.,0.,1.) 229 p6=Point(0.,1.,1.) 230 p7=Point(1.,1.,1.) 231 gross 2683 \end{python} 232 caltinay 3324 233 gross 2683 We connect the points to form the bottom and top surfaces of the cube: 234 \begin{python} 235 caltinay 3324 l01=Line(p0,p1) 236 l13=Line(p1,p3) 237 l32=Line(p3,p2) 238 l20=Line(p2,p0) 239 bottom=PlaneSurface(-CurveLoop(l01,l13,l32,l20)) 240 gross 2683 \end{python} 241 caltinay 3324 242 \begin{figure} 243 \centerline{\includegraphics{brick}} 244 \caption{Three dimensional block} 245 \label{fig:PYCAD 2} 246 \end{figure} 247 248 Similar to the definition of a \code{CurvedLoop} the orientation of the 249 surfaces in a \code{SurfaceLoop} is relevant. 250 In fact, the surface normal direction defined by the right-hand rule needs to 251 point outwards as indicated by the surface normals in Figure~\ref{fig:PYCAD 2}. 252 As the \code{bottom} face is directed upwards it is inserted with the minus 253 sign into the \code{SurfaceLoop} in order to adjust the orientation of the 254 surface. Similarly we set 255 gross 2683 \begin{python} 256 caltinay 3324 l45=Line(p4,p5) 257 l57=Line(p5,p7) 258 l76=Line(p7,p6) 259 l64=Line(p6,p4) 260 top=PlaneSurface(CurveLoop(l45,l57,l76,l64)) 261 gross 2683 \end{python} 262 caltinay 3324 To form the front face we introduce the two additional lines connecting the 263 left and right front points of the \code{top} and \code{bottom} face: 264 gross 2683 \begin{python} 265 caltinay 3324 l15=Line(p1,p5) 266 l40=Line(p4,p0) 267 gross 2683 \end{python} 268 sshaw 4972 To form the front face we encounter a problem, the line \code{l45} used 269 caltinay 3324 to define the \code{top} face is pointing the wrong direction. 270 sshaw 4972 In \pycad you can reverse the direction of an object by changing its sign. 271 caltinay 3324 So we write \code{-l45} to indicate that the direction is to be reversed. 272 With this notation we can write 273 gross 2683 \begin{python} 274 caltinay 3324 front=PlaneSurface(CurveLoop(l01,l15,-l45,l40)) 275 gross 2683 \end{python} 276 caltinay 3324 Keep in mind that if you use \code{Line(p4,p5)} instead of \code{-l45} both 277 objects are treated as different although connecting the same points with a 278 straight line in the same direction. The resulting geometry would include an 279 opening along the \code{p4}--\code{p5} connection. 280 This will lead to an inconsistent mesh and may result in a failure of the 281 volumetric mesh generator. Similarly we can define the other sides of the cube: 282 gross 2683 \begin{python} 283 caltinay 3324 l37=Line(p3,p7) 284 l62=Line(p6,p2) 285 back=PlaneSurface(CurveLoop(l32,-l62,-l76,-l37)) 286 left=PlaneSurface(CurveLoop(-l40,-l64,l62,l20)) 287 right=PlaneSurface(CurveLoop(-l15,l13,l37,-l57)) 288 gross 2683 \end{python} 289 caltinay 3324 We can now put the six surfaces together to form a \class{SurfaceLoop} 290 defining the boundary of the volume of the cube: 291 gross 2683 \begin{python} 292 caltinay 3324 sl=SurfaceLoop(top,bottom,front,back,left,right) 293 v=Volume(sl) 294 gross 2683 \end{python} 295 As in the 2D case, the \class{Design} class is used to define the geometry: 296 \begin{python} 297 caltinay 3324 from esys.pycad.gmsh import Design 298 from esys.finley import MakeDomain 299 ksteube 1066 300 caltinay 3324 des=Design(dim=3, element_size = 0.1, keep_files=True) 301 des.setScriptFileName("brick.geo") 302 des.addItems(v, top, bottom, back, front, left, right) 303 ksteube 1066 304 caltinay 3324 dom=MakeDomain(des) 305 dom.write("brick.fly") 306 gross 2683 \end{python} 307 caltinay 3293 Note that the \finley mesh file \file{brick.fly} will contain the 308 gross 2683 triangles used to define the surfaces as they are added to the \class{Design}. 309 The example script of the cube is included with the software in 310 caltinay 3293 \file{brick.py} in the \ExampleDirectory. 311 ksteube 1066 312 gross 2717 \section{Alternative File Formats} 313 caltinay 3324 \pycad supports other file formats including I-DEAS universal file, VRML, 314 Nastran and STL. The following example shows how to generate the STL file 315 \file{brick.stl}: 316 gross 2717 \begin{python} 317 caltinay 3324 from esys.pycad.gmsh import Design 318 gross 2717 319 caltinay 3324 des=Design(dim=3, element_size = 0.1, keep_files=True) 320 des.addItems(v, top, bottom, back, front, left , right) 321 gross 2717 322 caltinay 3324 des.setFileFormat(des.STL) 323 des.setMeshFileName("brick.stl") 324 des.generate() 325 gross 2717 \end{python} 326 The example script of the cube is included with the software in 327 caltinay 3293 \file{brick_stl.py} in the \ExampleDirectory. 328 gross 2717 329 caltinay 3324 \section{Element Sizes} 330 The element size used globally is defined by the \code{element_size} argument 331 of the \class{Design}. The mesh generator will try to use this mesh size 332 everywhere in the geometry. In some cases it can be desirable to use a finer 333 mesh locally. A local refinement can be defined at each \class{Point}: 334 \begin{python} 335 p0=Point(0., 0., 0., local_scale=0.01) 336 \end{python} 337 Here the mesh generator will create a mesh with an element size which is by 338 the factor \code{0.01} times smaller than the global mesh size 339 \code{element_size=0.3}, see Figure~\ref{fig:PYCAD 5}. 340 The point where a refinement is defined must be a point on a curve used to 341 define the geometry. 342 gross 2717 343 gross 2683 \begin{figure} 344 caltinay 3324 \centerline{\includegraphics{refine}} 345 \caption{Local refinement at the origin by \var{local_scale=0.01} 346 with \var{element_size=0.3} and number of elements on the top set to 10} 347 gross 2683 \label{fig:PYCAD 5} 348 \end{figure} 349 ksteube 1066 350 caltinay 3324 Alternatively, one can define a mesh size along a curve by defining the number 351 of elements to be used to subdivide the curve. For instance, to use $20$ 352 elements on line \code{l23}: 353 gross 2683 \begin{python} 354 caltinay 3324 l23=Line(p2, p3) 355 l23.setElementDistribution(20) 356 gross 2683 \end{python} 357 caltinay 3324 Setting the number of elements on a curve overwrites the global mesh size 358 \code{element_size}. The result is shown in Figure~\ref{fig:PYCAD 5}. 359 ksteube 1066 360 gross 999 \section{\pycad Classes} 361 caltinay 3306 %\declaremodule{extension}{esys.pycad} 362 %\modulesynopsis{Python geometry description and meshing interface} 363 gross 993 364 gross 999 \subsection{Primitives} 365 caltinay 3324 Some of the most commonly-used objects in \pycad are listed here. 366 For a more complete list see the full API documentation. 367 gross 993 368 gross 2429 \begin{classdesc}{Point}{x=0.,y=0.,z=0.\optional{,local_scale=1.}} 369 caltinay 3324 creates a point at the given coordinates with local characteristic length \var{local_scale} 370 gross 999 \end{classdesc} 371 372 gross 2935 \begin{classdesc}{CurveLoop}{list} 373 caltinay 3324 creates a closed curve from a \code{list} of 374 gross 2935 \class{Line}, \class{Arc}, \class{Spline}, \class{BSpline}, 375 caltinay 3324 \class{BezierSpline} objects. 376 gross 2935 \end{classdesc} 377 378 \begin{classdesc}{SurfaceLoop}{list} 379 caltinay 3324 creates a loop of \class{PlaneSurface} or \class{RuledSurface}, which defines 380 the shell of a volume. 381 gross 2935 \end{classdesc} 382 383 \subsubsection{Lines} 384 ksteube 1066 \begin{classdesc}{Line}{point1, point2} 385 caltinay 3324 creates a line between two points. 386 ksteube 1066 \end{classdesc} 387 caltinay 3324 388 gross 2429 \begin{methoddesc}[Line]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 389 caltinay 3324 defines the number of elements on the line. If set, it overwrites the local 390 length setting which would be applied. 391 The progression factor \var{progression} defines the change of element size 392 between neighboured elements. If \var{createBump} is set progression is 393 applied towards the centre of the line. 394 gross 2429 \end{methoddesc} 395 caltinay 3324 396 gross 2429 \begin{methoddesc}[Line]{resetElementDistribution}{} 397 removes a previously set element distribution from the line. 398 \end{methoddesc} 399 caltinay 3324 \begin{methoddesc}[Line]{getElementDistribution}{} 400 returns the element distribution as a tuple of number of elements, progression 401 factor and bump flag. If no element distribution is set None is returned. 402 gross 2429 \end{methoddesc} 403 gross 999 404 gross 2935 \subsubsection{Splines} 405 gross 2429 \begin{classdesc}{Spline}{point0, point1, ...} 406 caltinay 3324 A spline curve defined by a list of points \var{point0}, \var{point1}, \ldots 407 gross 999 \end{classdesc} 408 caltinay 3324 409 gross 2429 \begin{methoddesc}[Spline]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 410 caltinay 3324 defines the number of elements on the spline. If set, it overwrites the local 411 length setting which would be applied. 412 The progression factor \var{progression} defines the change of element size 413 between neighboured elements. If \var{createBump} is set progression is 414 applied towards the centre of the spline. 415 gross 2429 \end{methoddesc} 416 caltinay 3324 417 gross 2429 \begin{methoddesc}[Spline]{resetElementDistribution}{} 418 caltinay 3324 removes a previously set element distribution from the spline. 419 gross 2429 \end{methoddesc} 420 caltinay 3324 421 \begin{methoddesc}[Spline]{getElementDistribution}{} 422 returns the element distribution as a tuple of number of elements, progression 423 factor and bump flag. If no element distribution is set None is returned. 424 gross 2429 \end{methoddesc} 425 gross 999 426 gross 2935 \subsubsection{BSplines} 427 gross 2429 \begin{classdesc}{BSpline}{point0, point1, ...} 428 caltinay 3324 A B-spline curve defined by a list of points \var{point0}, \var{point1}, \ldots 429 ksteube 1066 \end{classdesc} 430 caltinay 3324 431 gross 2429 \begin{methoddesc}[BSpline]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 432 caltinay 3324 defines the number of elements on the curve. If set, it overwrites the local 433 length setting which would be applied. 434 The progression factor \var{progression} defines the change of element size 435 between neighboured elements. If \var{createBump} is set progression is 436 applied towards the centre of the curve. 437 gross 2429 \end{methoddesc} 438 caltinay 3324 439 gross 2429 \begin{methoddesc}[BSpline]{resetElementDistribution}{} 440 caltinay 3324 removes a previously set element distribution from the curve. 441 gross 2429 \end{methoddesc} 442 caltinay 3324 443 \begin{methoddesc}[BSpline]{getElementDistribution}{} 444 returns the element distribution as a tuple of number of elements, progression 445 factor and bump flag. If no element distribution is set None is returned. 446 gross 2429 \end{methoddesc} 447 gross 999 448 caltinay 3324 \subsubsection{Bezier Curves} 449 gross 2429 \begin{classdesc}{BezierCurve}{point0, point1, ...} 450 caltinay 3324 A Bezier spline curve defined by a list of points \var{point0}, \var{point1}, \ldots 451 gross 999 \end{classdesc} 452 caltinay 3324 453 gross 2429 \begin{methoddesc}[BezierCurve]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 454 caltinay 3324 defines the number of elements on the curve. If set, it overwrites the local 455 length setting which would be applied. 456 The progression factor \var{progression} defines the change of element size 457 between neighboured elements. If \var{createBump} is set progression is 458 applied towards the centre of the curve. 459 gross 2429 \end{methoddesc} 460 caltinay 3324 461 gross 2429 \begin{methoddesc}[BezierCurve]{resetElementDistribution}{} 462 caltinay 3324 removes a previously set element distribution from the curve. 463 gross 2429 \end{methoddesc} 464 caltinay 3324 465 \begin{methoddesc}[BezierCurve]{getElementDistribution}{} 466 returns the element distribution as a tuple of number of elements, progression 467 factor and bump flag. If no element distribution is set None is returned. 468 gross 2429 \end{methoddesc} 469 gross 999 470 gross 2935 \subsubsection{Arcs} 471 gross 2683 \begin{classdesc}{Arc}{centre_point, start_point, end_point} 472 caltinay 3324 creates an arc by specifying a centre for a circle and start and end points. 473 An arc may subtend an angle of at most $\pi$ radians. 474 ksteube 1066 \end{classdesc} 475 caltinay 3324 476 gross 2429 \begin{methoddesc}[Arc]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 477 caltinay 3324 defines the number of elements on the arc. If set, it overwrites the local 478 length setting which would be applied. 479 The progression factor \var{progression} defines the change of element size 480 between neighboured elements. If \var{createBump} is set progression is 481 applied towards the centre of the arc. 482 gross 2429 \end{methoddesc} 483 caltinay 3324 484 gross 2429 \begin{methoddesc}[Arc]{resetElementDistribution}{} 485 caltinay 3324 removes a previously set element distribution from the arc. 486 gross 2429 \end{methoddesc} 487 caltinay 3324 488 \begin{methoddesc}[Arc]{getElementDistribution}{} 489 returns the element distribution as a tuple of number of elements, progression 490 factor and bump flag. If no element distribution is set None is returned. 491 gross 2429 \end{methoddesc} 492 gross 999 493 caltinay 3324 \subsubsection{Plane surfaces} 494 ksteube 1066 \begin{classdesc}{PlaneSurface}{loop, \optional{holes=[list]}} 495 caltinay 3324 creates a plane surface from a \class{CurveLoop}, which may have one or more 496 holes described by a \var{list} of \class{CurveLoop} objects. 497 ksteube 1066 \end{classdesc} 498 caltinay 3324 499 gross 2935 \begin{methoddesc}[PlaneSurface]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 500 caltinay 3324 defines the number of elements on all lines. 501 gross 2935 \end{methoddesc} 502 503 \begin{methoddesc}[PlaneSurface]{setRecombination}{\optional{max_deviation=45 * \var{DEG} }} 504 caltinay 3324 the mesh generator will try to recombine triangular elements into 505 quadrilateral elements. \var{max_deviation} (in radians) defines the 506 caltinay 3293 maximum deviation of any angle in the quadrilaterals from the right angle. 507 gross 2429 Set \var{max_deviation}=\var{None} to remove recombination. 508 \end{methoddesc} 509 caltinay 3324 510 gross 2429 \begin{methoddesc}[PlaneSurface]{setTransfiniteMeshing}{\optional{orientation="Left"}} 511 caltinay 3293 applies 2D transfinite meshing to the surface. 512 gross 2429 \var{orientation} defines the orientation of triangles. Allowed values 513 caltinay 3324 are \var{Left''}, \var{Right''} and \var{Alternate''}. 514 The boundary of the surface must be defined by three or four lines and an 515 caltinay 3293 element distribution must be defined on all faces where opposite 516 caltinay 3324 faces use the same element distribution. No holes must be present. 517 gross 2429 \end{methoddesc} 518 ksteube 1066 519 gross 2935 \subsubsection{Ruled Surfaces} 520 ksteube 1066 \begin{classdesc}{RuledSurface}{list} 521 caltinay 3324 creates a surface that can be interpolated using transfinite interpolation. 522 gross 2429 \var{list} gives a list of three or four lines defining the boundary of the 523 surface. 524 ksteube 1066 \end{classdesc} 525 gross 2935 526 \begin{methoddesc}[RuledSurface]{setRecombination}{\optional{max_deviation=45 * \var{DEG} }} 527 caltinay 3324 the mesh generator will try to recombine triangular elements into 528 quadrilateral elements. \var{max_deviation} (in radians) defines the 529 caltinay 3293 maximum deviation of any angle in the quadrilaterals from the right angle. 530 gross 2429 Set \var{max_deviation}=\var{None} to remove recombination. 531 \end{methoddesc} 532 gross 2935 533 gross 2429 \begin{methoddesc}[RuledSurface]{setTransfiniteMeshing}{\optional{orientation="Left"}} 534 caltinay 3293 applies 2D transfinite meshing to the surface. 535 gross 2429 \var{orientation} defines the orientation of triangles. Allowed values 536 caltinay 3324 are \var{Left''}, \var{Right''} and \var{Alternate''}. 537 The boundary of the surface must be defined by three or four lines and an 538 caltinay 3293 element distribution must be defined on all faces where opposite 539 caltinay 3324 faces use the same element distribution. No holes must be present. 540 gross 2429 \end{methoddesc} 541 ksteube 1066 542 gross 2935 \begin{methoddesc}[RuledSurface]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 543 caltinay 3324 defines the number of elements on all lines. 544 gross 2935 \end{methoddesc} 545 gross 2429 546 gross 2935 \subsubsection{Volumes} 547 ksteube 1066 \begin{classdesc}{Volume}{loop, \optional{holes=[list]}} 548 caltinay 3324 creates a volume given a \class{SurfaceLoop}, which may have one or more holes 549 gross 2429 define by the list of \class{SurfaceLoop}. 550 ksteube 1066 \end{classdesc} 551 552 gross 2935 \begin{methoddesc}[Volume]{setElementDistribution}{n\optional{,progression=1\optional{,createBump=\False}}} 553 caltinay 3324 defines the number of elements on all lines. 554 gross 2935 \end{methoddesc} 555 ksteube 1066 556 gross 2935 \begin{methoddesc}[Volume]{setRecombination}{\optional{max_deviation=45 * \var{DEG} }} 557 caltinay 3324 the mesh generator will try to recombine triangular elements into 558 quadrilateral elements. These meshes are then used to generate the volume mesh 559 if possible. 560 Together with transfinite meshing one can construct rectangular meshes. 561 \var{max_deviation} (in radians) defines the maximum deviation of any angle in 562 the quadrilaterals from the right angle. 563 gross 2935 Set \var{max_deviation}=\var{None} to remove recombination. 564 \end{methoddesc} 565 566 \begin{methoddesc}[Volume]{setTransfiniteMeshing}{\optional{orientation="Left"}} 567 caltinay 3324 applies transfinite meshing to the volume and all surfaces (if 568 \var{orientation} is not equal to \var{None}). 569 gross 2935 \var{orientation} defines the orientation of triangles. Allowed values 570 caltinay 3324 are \var{Left''}, \var{Right''} and \var{Alternate''}. 571 The boundary of the surface must be defined by three or four lines and an 572 caltinay 3293 element distribution must be defined on all faces where opposite 573 caltinay 3324 faces use the same element distribution. 574 If \var{orientation} is equal to \var{None} transfinite meshing is not 575 switched on for the surfaces but needs to be set by the user. 576 No holes must be present. 577 \textbf{Warning: The functionality of transfinite meshing without 578 recombination is not entirely clear in \gmshextern. 579 gross 2936 So please apply this method with care.} 580 gross 2935 \end{methoddesc} 581 582 caltinay 3324 %============================================================================ 583 gross 999 \subsection{Transformations} 584 585 caltinay 3324 Sometimes it is convenient to create an object and then make copies at 586 different orientations or in different sizes. This can be achieved by 587 applying transformations which are used to move geometrical objects in the 588 3-dimensional space and to resize them. 589 gross 999 590 \begin{classdesc}{Translation}{\optional{b=[0,0,0]}} 591 caltinay 3324 defines a translation $x \to x+b$. \var{b} can be any object that can be 592 converted into a \numpy object of shape $(3,)$. 593 gross 999 \end{classdesc} 594 caltinay 3293 595 gross 3179 \begin{classdesc}{Rotation}{\optional{axis=[1,1,1], \optional{ point = [0,0,0], \optional{angle=0*RAD} } } } 596 caltinay 3293 defines a rotation by \var{angle} around axis through point \var{point} and direction \var{axis}. 597 caltinay 3324 \var{axis} and \var{point} can be any object that can be converted into a 598 \numpy object of shape $(3,)$. 599 \var{axis} does not have to be normalised but must have positive length. 600 The right-hand rule~\cite{RIGHTHANDRULE} applies. 601 gross 999 \end{classdesc} 602 603 gross 2683 \begin{classdesc}{Dilation}{\optional{factor=1., \optional{centre=[0,0,0]}}} 604 caltinay 3293 defines a dilation by the expansion/contraction \var{factor} with 605 gross 2683 \var{centre} as the dilation centre. 606 caltinay 3324 \var{centre} can be any object that can be converted into a \numpy object of 607 shape $(3,)$. 608 gross 999 \end{classdesc} 609 610 \begin{classdesc}{Reflection}{\optional{normal=[1,1,1], \optional{offset=0}}} 611 caltinay 3293 defines a reflection on a plane defined in normal form $n^t x = d$ 612 gross 999 where $n$ is the surface normal \var{normal} and $d$ is the plane \var{offset}. 613 caltinay 3324 \var{normal} can be any object that can be converted into a \numpy object of 614 shape $(3,)$. 615 caltinay 3293 \var{normal} does not have to be normalised but must have positive length. 616 gross 999 \end{classdesc} 617 618 ksteube 1066 \begin{datadesc}{DEG} 619 caltinay 3324 a constant to convert from degrees to an internal angle representation in 620 radians. For instance use \code{90*DEG} for $90$ degrees. 621 ksteube 1066 \end{datadesc} 622 623 gross 999 \subsection{Properties} 624 ksteube 1066 If you are building a larger geometry you may find it convenient to 625 caltinay 3324 create it in smaller pieces and then assemble them. 626 Property Sets make this easy, and they allow you to name the smaller 627 ksteube 1066 pieces for convenience. 628 gross 999 629 caltinay 3324 Property Sets are used to bundle a set of geometrical objects in a 630 group. The group is identified by a name. Typically a Property Set 631 is used to mark subregions which share the same material properties or 632 to mark portions of the boundary. For efficiency, the \Design class 633 assigns an integer to each of its Property Sets, a so-called tag\index{tag}. 634 The appropriate tag is attached to the elements at generation time. 635 gross 1044 636 ksteube 1066 See the file \code{pycad/examples/quad.py} for an example using a {\it PropertySet}. 637 638 gross 999 \begin{classdesc}{PropertySet}{name,*items} 639 defines a group geometrical objects which can be accessed through a \var{name} 640 The objects in the tuple \var{items} mast all be \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD objects. 641 \end{classdesc} 642 643 \begin{methoddesc}[PropertySet]{getManifoldClass}{} 644 caltinay 3324 returns the manifold class \ManifoldOneD, \ManifoldTwoD or \ManifoldThreeD 645 expected from the items in the property set. 646 gross 999 \end{methoddesc} 647 648 \begin{methoddesc}[PropertySet]{getDim}{} 649 caltinay 3324 returns the spatial dimension of the items in the property set. 650 gross 999 \end{methoddesc} 651 652 \begin{methoddesc}[PropertySet]{getName}{} 653 returns the name of the set 654 \end{methoddesc} 655 656 \begin{methoddesc}[PropertySet]{setName}{name} 657 sets the name. This name should be unique within a \Design. 658 \end{methoddesc} 659 660 \begin{methoddesc}[PropertySet]{addItem}{*items} 661 caltinay 3324 adds a tuple of items. They need to be objects of class \ManifoldOneD, 662 \ManifoldTwoD or \ManifoldThreeD. 663 gross 999 \end{methoddesc} 664 665 \begin{methoddesc}[PropertySet]{getItems}{} 666 returns the list of items 667 \end{methoddesc} 668 669 \begin{methoddesc}[PropertySet]{clearItems}{} 670 caltinay 3293 clears the list of items 671 gross 999 \end{methoddesc} 672 673 \begin{methoddesc}[PropertySet]{getTag}{} 674 returns the tag used for this property set 675 \end{methoddesc} 676 677 ksteube 1066 \section{Interface to the mesh generation software} 678 caltinay 3306 %\declaremodule{extension}{esys.pycad.gmsh} 679 %\modulesynopsis{Python geometry description and meshing interface} 680 gross 999 681 ksteube 1066 The class and methods described here provide an interface to the mesh 682 caltinay 3324 generation software, which is currently \gmshextern. This interface could be 683 adopted to \emph{triangle} or another mesh generation package if this is 684 lgraham 1700 deemed to be desirable in the future. 685 ksteube 1066 686 gross 999 \begin{classdesc}{Design}{ 687 \optional{dim=3, \optional{element_size=1., \optional{order=1, \optional{keep_files=False}}}}} 688 caltinay 3324 describes the geometry defined by primitives to be meshed. 689 \var{dim} specifies the spatial dimension, while \var{element_size} defines 690 the global element size which is multiplied by the local scale to set the 691 element size at each \Point. 692 The argument \var{order} defines the element order to be used. 693 If \var{keep_files} is set to \True temporary files are kept, otherwise they 694 are removed when the instance of the class is deleted. 695 gross 999 \end{classdesc} 696 697 gross 2717 \begin{memberdesc}[Design]{GMSH} 698 caltinay 3324 gmsh file format~\cite{GMSH} 699 gross 2717 \end{memberdesc} 700 701 \begin{memberdesc}[Design]{IDEAS} 702 caltinay 3324 I-DEAS universal file format~\cite{IDEAS} 703 gross 2717 \end{memberdesc} 704 705 \begin{memberdesc}[Design]{VRML} 706 caltinay 3324 VRML file format, \cite{VRML} 707 gross 2717 \end{memberdesc} 708 709 \begin{memberdesc}[Design]{STL} 710 caltinay 3324 STL file format~\cite{STL} 711 gross 2717 \end{memberdesc} 712 caltinay 3324 713 gross 2717 \begin{memberdesc}[Design]{NASTRAN} 714 caltinay 3324 NASTRAN bulk data format~\cite{NASTRAN} 715 gross 2717 \end{memberdesc} 716 717 \begin{memberdesc}[Design]{MEDIT} 718 caltinay 3324 Medit file format~\cite{MEDIT} 719 gross 2717 \end{memberdesc} 720 721 \begin{memberdesc}[Design]{CGNS} 722 caltinay 3324 CGNS file format~\cite{CGNS} 723 gross 2717 \end{memberdesc} 724 725 \begin{memberdesc}[Design]{PLOT3D} 726 caltinay 3324 Plot3D file format~\cite{PLOT3D} 727 gross 2717 \end{memberdesc} 728 729 \begin{memberdesc}[Design]{DIFFPACK} 730 caltinay 3324 Diffpack 3D file format~\cite{DIFFPACK} 731 gross 2717 \end{memberdesc} 732 733 \begin{memberdesc}[Design]{DELAUNAY} 734 caltinay 3324 the Delaunay triangulator, see \gmshextern and \cite{TETGEN} 735 gross 2717 \end{memberdesc} 736 737 gross 3002 \begin{memberdesc}[Design]{MESHADAPT} 738 caltinay 3324 the gmsh triangulator, see \gmshextern 739 gross 2717 \end{memberdesc} 740 741 gross 3002 \begin{memberdesc}[Design]{FRONTAL} 742 caltinay 3324 the NETGEN~\cite{NETGEN} triangulator 743 gross 2717 \end{memberdesc} 744 745 \begin{methoddesc}[Design]{generate}{} 746 caltinay 3324 generates the mesh file. The data are written to the file \var{Design.getMeshFileName}. 747 gross 2717 \end{methoddesc} 748 749 gross 999 \begin{methoddesc}[Design]{setDim}{\optional{dim=3}} 750 sets the spatial dimension which needs to be $1$, $2$ or $3$. 751 \end{methoddesc} 752 753 \begin{methoddesc}[Design]{getDim}{} 754 returns the spatial dimension. 755 \end{methoddesc} 756 757 \begin{methoddesc}[Design]{setElementOrder}{\optional{order=1}} 758 sets the element order which needs to be $1$ or $2$. 759 \end{methoddesc} 760 761 \begin{methoddesc}[Design]{getElementOrder}{} 762 returns the element order. 763 \end{methoddesc} 764 765 \begin{methoddesc}[Design]{setElementSize}{\optional{element_size=1}} 766 caltinay 3324 sets the global element size. The local element size at a point is defined as 767 the global element size multiplied by the local scale. 768 The element size must be positive. 769 gross 999 \end{methoddesc} 770 771 \begin{methoddesc}[Design]{getElementSize}{} 772 returns the global element size. 773 \end{methoddesc} 774 775 \begin{methoddesc}[Design]{setKeepFilesOn}{} 776 work files are kept at the end of the generation. 777 \end{methoddesc} 778 779 \begin{methoddesc}[Design]{setKeepFilesOff}{} 780 work files are deleted at the end of the generation. 781 \end{methoddesc} 782 783 \begin{methoddesc}[Design]{keepFiles}{} 784 caltinay 3324 returns \True if work files are kept, \False otherwise. 785 gross 999 \end{methoddesc} 786 787 \begin{methoddesc}[Design]{setScriptFileName}{\optional{name=None}} 788 caltinay 3324 sets the file name for the gmsh input script. 789 If no name is given a name with extension "geo" is generated. 790 gross 999 \end{methoddesc} 791 792 \begin{methoddesc}[Design]{getScriptFileName}{} 793 ksteube 1066 returns the name of the file for the gmsh script. 794 gross 999 \end{methoddesc} 795 796 \begin{methoddesc}[Design]{setMeshFileName}{\optional{name=None}} 797 caltinay 3324 sets the name for the mesh file. If no name is given a name is generated. 798 The format is set by \\\var{Design.setFileFormat}. 799 gross 999 \end{methoddesc} 800 801 \begin{methoddesc}[Design]{getMeshFileName}{} 802 caltinay 3324 returns the name of the mesh file. 803 gross 999 \end{methoddesc} 804 805 \begin{methoddesc}[Design]{addItems}{*items} 806 caltinay 3324 adds the tuple of \var{items}. An item can be any primitive or a 807 \class{PropertySet}. 808 caltinay 3329 \warning{If a \PropertySet is added which includes an object that is not 809 part of a \PropertySet, it may not be considered in the meshing.} 810 gross 999 \end{methoddesc} 811 812 \begin{methoddesc}[Design]{getItems}{} 813 caltinay 3324 returns a list of the items. 814 gross 999 \end{methoddesc} 815 816 \begin{methoddesc}[Design]{clearItems}{} 817 caltinay 3324 resets the items in this design. 818 gross 999 \end{methoddesc} 819 820 \begin{methoddesc}[Design]{getMeshHandler}{} 821 caltinay 3324 returns a handle to the mesh. 822 Calling this method generates the mesh from the geometry and returns a 823 mechanism to access the mesh data. In the current implementation this 824 gross 2717 method returns a file name for a file containing the mesh data. 825 gross 999 \end{methoddesc} 826 827 \begin{methoddesc}[Design]{getScriptString}{} 828 ksteube 1066 returns the gmsh script to generate the mesh as a string. 829 gross 999 \end{methoddesc} 830 831 \begin{methoddesc}[Design]{getCommandString}{} 832 caltinay 3324 returns the gmsh command used to generate the mesh as a string. 833 gross 999 \end{methoddesc} 834 835 gross 3002 \begin{methoddesc}[Design]{setOptions}{ 836 sshaw 4554 \optional{algorithm=None 837 \optional{, optimize_quality=\True 838 caltinay 3293 \optional{, smoothing=1 839 sshaw 4554 \optional{, curvature_based_element_size=\False 840 \optional{, algorithm2D=None 841 \optional{, algorithm3D=None 842 \optional{, generate_hexahedra=False 843 \optional{, random_factor=None}}}}}}}}} 844 caltinay 3324 sets options for the mesh generator. 845 sshaw 4554 Both \var{algorithm} and \var{algorithm2D} set the 2D meshing algorithm to be 846 used. If both parameters are given, they must be equal. 847 caltinay 3324 The algorithm needs to be \var{Design.DELAUNAY}, \var{Design.FRONTAL}, 848 caltinay 3293 or \var{Design.MESHADAPT}. By default \var{Design.MESHADAPT} is used. 849 gross 3002 \var{algorithm3D} sets the 3D meshing algorithm to be used. 850 caltinay 3324 The algorithm needs to be \var{Design.DELAUNAY} or \var{Design.FRONTAL}. 851 By default \var{Design.FRONTAL} is used. 852 gross 3002 \var{optimize_quality}=\True invokes an optimization of the mesh quality. 853 caltinay 3293 \var{smoothing} sets the number of smoothing steps to be applied to the mesh. 854 caltinay 3324 \var{curvature_based_element_size}=\True switches on curvature based 855 definition of element size. 856 \var{generate_hexahedra}=\True switches on the usage of quadrilateral or 857 hexahedral elements. 858 sshaw 4554 \var{random_factor} a positive amount used in the 2D meshing algorithm. 859 gross 999 \end{methoddesc} 860 861 \begin{methoddesc}[Design]{getTagMap}{} 862 caltinay 3324 returns a \class{TagMap} to map the \class{PropertySet} names to tag numbers 863 generated by gmsh. 864 gross 999 \end{methoddesc} 865 gross 2717 866 \begin{methoddesc}[Design]{setFileFormat}{\optional{format=\var{Design.GMSH}}} 867 caltinay 3324 sets the file format. \var{format} must be one of the values:\\ 868 \var{Design.GMSH}\\ 869 jfenwick 3301 \var{Design.IDEAS}\\ 870 \var{Design.VRML}\\ 871 \var{Design.STL}\\ 872 \var{Design.NASTRAN}\\ 873 \var{Design.MEDIT}\\ 874 \var{Design.CGNS}\\ 875 \var{Design.PLOT3D}\\ 876 gross 2717 \var{Design.DIFFPACK}. 877 \end{methoddesc} 878 879 gross 2793 \begin{methoddesc}[Design]{getFileFormat}{} 880 gross 2717 returns the file format. 881 gross 3179 \end{methoddesc} 882 caltinay 3324