CIG Tutorial

This example creates a circle in a square (similar to the function createCircleInSquare).


Setting up the input generator

The Concepts Input Generator is defined in the cig module, therefore include cig. We also define a few variables which we will use for a more flexible example.

from cig import *

#Properties
size=3   #Physical length/width of the square
r=1      #Radius
attr1=1  #Attribute outside the circle
attr2=2  #Inner attribute

Creating a cell

There are two different classes to describe a cell, PeriodicCell and Cell. Cell is the base class and can be used for all sorts of meshes, it has no restrictions but offers no support for special cases. PeriodicCell is a child-class of Cell and should be used for Cells which are shaped like parallelograms or rectangles. It knows its border and it can merge parallelograms together. The methods PeriodicCell::setBorder and PeriodicCell::setBorderAngle are used to define the border. Set border takes a vectors which spawns the cell, the size in and the number of points (including corners) in both directions. PeriodicCell::setBorderAngle can be set the borders by specifying an angle rather than two vectors.

In our example we will create a square cell. Therefore we will use a PeriodicCell with the two vectors (1,0) and (0,1).

#Create the cell
e=PeriodicCell()
e.setBorder(1,0,size,2,0,1,size,2) #setBorder(vector1X,vector1Y,sizeVecor1,n,vecor2X,vector2Y,sizeVector2,m)
                                                #Vector1: (1,0) with length size and two points on the border (the corners)
                                                #Vector2: (0,1) 

Defining materials and additional properties

We have now defined a Cell, but another important point are the materials. CIG usually takes a materialNumber for every quad. To make a meaningful simulation, we need to assign physical properties to those materials. In our case, we will use just two different materials, the first for the area inside the circle and the second for everything outside. The function to set a material is addMaterial(name,epsilon,number). It is possible to define some additional properties, like a title or a author name in the project file. These strings will also be given to concepts. All known strings are defined in the example code

#Materials
e.addMaterial('Test material 1',1.111,attr1)
e.addMaterial('Test material 1',1.111,attr2)

#General Information
e.title="Tutorial: Circle in cell"
e.author="Sandro Belfanti"
e.comment="Example for the Tutorial, 20. Sept 08"
e.path="."
e.output="Tutorial1"                                  #For the filename of the concepts output

Creating objects

The next step is to think about how to mesh our cell. We will create a Circle which contains a square (a circle is not a valid quad even though it contains 4 nodes, since the nodes are 'hanging nodes', that is nodes with angles = 180 degree). (PICTURE needed!) We will use the circle(x,y,r) function to create our circle. The created circle has points at (mx-r,my), (mx+r,my), (mx,my-r), (mx,my+r). (Left Right Top Bottom). Because we would prefer if the points were directed towards the corners of our cell, we will rotate it by 45 degree. The square will be generated by Cell::rect(x1,y1,x2,y2,Attribute).

[mx,my]=e.getMiddlePoint() # Function from PeriodicCell

circ=e.circle(mx,my,r)  #Points at (mx-r,my), (mx+r,my), (mx,my-r), (mx,my+r)
e.rotateQuad(circ,pi/4,mx,my)
centerRect=e.rect(mx-r/2.0,my-r/2.0,mx+r/2.0,my+r/2.0,attr2)

Meshing

Now we have added all points and all lines with a radius to our cell. Now we can just connect the points to quads. We will create 8 additional quads, 4 outside the circle and 4 inside. P.E. we will connect the top-left corner of the cell, the top-right corner, the top left point of the circle and the top.right point of the circle to a first quad. Similarly for all the other quads. Because we don't know the exact location of the points on the circle after rotation we will use Cell::getClosestPoint(Nr,obj) (of course, we could also calculate the positions it if we wanted...). This function will return the point in obj which is closest to point number Nr. Instead of Nr we could also use [x,y]. obj can be the number of a quad, a list of quad numbers or a string 'all'. In our case getClosestPoint(Corner1,circ) will return the point on the circle which is closest to corner1. Since PeriodicCell knows its borders and therefore its corners, we can just get a list with all 4 corners by using PeriodicCell::getCorners(). The use of a list of corners will allow us to do all the work in a single loop. To add the points we will use Cell:addQuad(Nr1,Nr2,Nr3,Nr4,Attr). It would return the Number of the added quad, but we don't need it anymore.

corners=e.getCorners()   #Returns the points in the following order Top Left, Top Right, Bottom Right, Bottom Left
                                       #but we actually don't need to know the order for our purpose

for i in range(len(corners)): #len(corners) is 4, since a quad allways has 4 corners...
   #Get the two corners for the quad
   corner1=corners[i]
   corner2=corners[(i+1)%len(corners)]
   
   pCircle1=e.getClosestPoint(corner1,circ)
   pCircle2=e.getClosestPoint(corner2,circ)
   
   pRect1=e.getClosestPoint(corner1,centerRect)
   pRect2=e.getClosestPoint(corner2,centerRect)
   
   #The actual addition
   e.addQuad(corner1,corner2,pCircle2,pCircle1,attr1)
   e.addQuad(pCircle1,pCircle2,pRect2,pRect1,attr2)

Finish

There is one last technicality, we need to delete the circle because it is overlapping with a lot of other quads (it has been replaced by them). The issue of overlapping quads is not solved yet, therefore we have to delete it manually. If we want to start a gui we can use e.drawGUI() or e.startThread().

e.deleteQuad(circ) #Overlapping quads: not deleted automatically
e.drawGUI()

The complete code

#You always have to import cig to use the concepts input generator
from cig import *

#Properties
size=3   #Physical length/width of the square
r=1      #Radius
attr1=1  #Attribute outside the circle
attr2=2  #Inner attribute

#Create the cell
#PeriodicCell is a parallelogram, it knows its border. 
#The setBorder function takes to vectors which spawn the Cell, but since we want
#to create a square we use just (1,0) and (0,1)
e=PeriodicCell()
e.setBorder(1,0,size,2,0,1,size,2) #setBorder(vector1X,vector1Y,sizeVecor1,n,vecor2X,vector2Y,sizeVector2,m)
                                                #Vector1: (1,0) with length size and two points on the border (the corners)
                                                #Vector2: (0,1) 

#Materials
e.addMaterial('Test material 1',1.111,attr1)
e.addMaterial('Test material 1',1.111,attr2)

#General Information
e.title="Tutorial: Circle in cell"
e.author="Sandro Belfanti"
e.comment="Example for the Tutorial, 20. Sept 08"
e.path="."
e.output="Tutorial1"                                  #For the filename of the concepts output

[mx,my]=e.getMiddlePoint()

circ=e.circle(mx,my,r)
e.rotateQuad(circ,pi/4,mx,my)
centerRect=e.rect(mx-r/2.0,my-r/2.0,mx+r/2.0,my+r/2.0,attr2)

corners=e.getCorners()   #Top Left, Top Right, Bottom Right, Bottom Left

for i in range(len(corners)):
   corner1=corners[i]
   corner2=corners[(i+1)%len(corners)]
   
   pCircle1=e.getClosestPoint(corner1,circ)
   pCircle2=e.getClosestPoint(corner2,circ)
   
   pRect1=e.getClosestPoint(corner1,centerRect)
   pRect2=e.getClosestPoint(corner2,centerRect)
   
   e.addQuad(corner1,corner2,pCircle2,pCircle1,attr1)
   e.addQuad(pCircle1,pCircle2,pRect2,pRect1,attr2)
   
   
e.deleteQuad(circ) #Overlapping quads: not deleted automatically

e.drawGUI()

Next Steps

We have created a cell, the next step could be to merge several cells together. The merge function takes three arguments: the cells to merge and a string which specifies where to attach the second cell: 'up','down','right','left'. The cells which are merged should have the same size, angle and border points.

f=merge(e,e,'up')
g=merge(f,e)

More general example

Note that it is very easy to change this example to a circle in a parallelogram. Because we never used "hard coded" coordinates for our points and we never calculated anything manually we just have to adjust a few lines:
  • e.setBorder(1,0,size,2,0,1,size,2): We want to create a parallelogram with angle alpha: e.setBorderAngle(alpha,sizeX,sizeY,2,2)
  • e.rotateQuad(circ,pi/4,mx,my): Rather than rotating by 90 degrees, we use a new angle: beta=-math.atan(sizeY*math.sin(alpha)/(sizeY*math.cos(alpha)+sizeX)) e.rotateQuad(circ,beta,mx,my)
  • e.rotateQuad(centerRect,beta-pi/4,mx,my): We also have to rotate the rectangle in the center, if the cell is no longer a square
The complete Code ist given at the end

ToDo's

  • Use Links to the documentation (as soon as we have the documentation in the right place).
  • Import a picture of the generated mesh (if possible).
  • Insert a check if r is not too big. Or at least state that this check was omitted.

Code for the extended example

This time the code is put in a function, for easier reuse. The same function is also included in cig (same name, same arguments).


def createCircleInParallelogram(sizeX,sizeY,r,alpha,attr1,attr2):
   e=PeriodicCell()
   e.setBorderAngle(alpha,sizeX,sizeY,2,2) #Changed: size ==> sizeX, sizeY

   [mx,my]=e.getMiddlePoint()

   beta=-math.atan(sizeY*math.sin(alpha)/(sizeY*math.cos(alpha)+sizeX))

   circ=e.circle(mx,my,r)
   e.rotateQuad(circ,beta,mx,my)
   centerRect=e.rect(mx-r/2.0,my-r/2.0,mx+r/2.0,my+r/2.0,attr2)
   e.rotateQuad(centerRect,beta-pi/4,mx,my)

   corners=e.getCorners()   #Top Left, Top Right, Bottom Right, Bottom Left

   for i in range(len(corners)):
      corner1=corners[i]
      corner2=corners[(i+1)%len(corners)]
      
      pCircle1=e.getClosestPoint(corner1,circ)
      pCircle2=e.getClosestPoint(corner2,circ)
      
      pRect1=e.getClosestPoint(corner1,centerRect)
      pRect2=e.getClosestPoint(corner2,centerRect)
      
      e.addQuad(corner1,corner2,pCircle2,pCircle1,attr1)
      e.addQuad(pCircle1,pCircle2,pRect2,pRect1,attr2)
      
      
   e.deleteQuad(circ)
   
   return e

Topic revision: r3 - 11 Sep 2023, KerstenSchmidt
This site is powered by FoswikiCopyright © by the contributing authors. All material on this site is the property of the contributing authors.
Ideas, requests, problems regarding Concepts? Send feedback