Difference between revisions of "HowTo blockMesh with m4"

From OpenFOAMWiki
m (Moved this from the FAQ)
 
(How to quickly change the mesh with blockMesh)
Line 24: Line 24:
 
The first four line of codes simply define a calculator, sets a variable <i>VCOUNT = 0</i> and defines a new way of defining vertices. The last four are for defining 2D cells, as well as patches for the boundaries. The b is short for the bottom and t for top, that is the bottom and top of the 2D cell set.   
 
The first four line of codes simply define a calculator, sets a variable <i>VCOUNT = 0</i> and defines a new way of defining vertices. The last four are for defining 2D cells, as well as patches for the boundaries. The b is short for the bottom and t for top, that is the bottom and top of the 2D cell set.   
  
So imagine we want to create a vertex at the position (2,4,8), instead of:
+
So imagine we want to create a 2D channel with an inlet outlet and wall boundary conditions, first off we define the coordinates of the channel:
  
 
<cpp>
 
<cpp>
vertices
+
define(side, 100.0)
    (
+
define(height, 300.0)
        (2 4 8)
+
define(nrcellsx, 10)
    )
+
define(nrcellsy, 30)
 +
define(origox, 0.0)
 +
define(origoy, 0.0)
 +
define(coordinatesidex, calc(origox+side))
 +
define(coordinatesidey, calc(origoy+height))
 +
 
 +
define(Z1, 0.0)
 +
define(Z2, 1.0)
 
</cpp>
 
</cpp>
  
We can now type:
+
Then we want to define the actual vertices:
 
+
 
<cpp>
 
<cpp>
define(Ax, 2)
+
 
define(Ay, calc(2*Ax))
+
define(Az, calc(2*Ay))
+
  
 
vertices
 
vertices
 
     (
 
     (
        (Ax Ay Az) vlabel(a1b)
+
    (origox origoy Z1) vlabel(a1b)
 +
    (coordinatesidex origoy Z1) vlabel(a2b)
 +
    (coordinatesidex coordinatesidey Z1) vlabel(a3b)
 +
    (origox coordinatesidey Z1) vlabel(a4b)
 +
 
 +
    (origox origoy Z2) vlabel(a1t)
 +
    (coordinatesidex origoy Z2) vlabel(a2t)
 +
    (coordinatesidex coordinatesidey Z2) vlabel(a3t)
 +
    (origox coordinatesidey Z2) vlabel(a4t)
 
     )
 
     )
 
</cpp>
 
</cpp>
Then, assuming <i>a1t, a2b,a2t,b1b,b1t, b2b,</i> and <i>b2t</i> has been defined, the definition of a block is simply:
+
 
 +
We can now define the block:
  
 
<cpp>
 
<cpp>
 
blocks
 
blocks
 +
(
 +
    // block0
 +
    hex2D(a1, a2, a3, a4)
 +
    (nrcellsx nrcellsy 1)
 +
    simpleGrading (1 1 1)
 +
);
 +
 +
</cpp>
 +
Then, the boundary conditions is simply:
 +
 +
<cpp>
 +
patches
 +
 +
(
 +
    patch inlet
 
     (
 
     (
        hex2D(a1, b1, b2, a2)
+
quad2D(a1,a2)
 
     )
 
     )
 +
 +
    patch outlet
 +
    (
 +
quad2D(a3,a4)
 +
    )
 +
 +
    empty back
 +
    (
 +
backQuad(a1,a2,a3,a4)
 +
    )
 +
 +
    empty front
 +
    (
 +
frontQuad(a1,a2,a3,a4)
 +
    )
 +
 +
    wall
 +
    wall
 +
    (
 +
quad2D(a1,a4)
 +
quad2D(a2,a3)
 +
    )
 +
);
 +
 
</cpp>
 
</cpp>
  

Revision as of 10:47, 1 February 2006

How to quickly change the mesh with blockMesh

The Gnu preprocessor m4 is handy for parametric refinement to the mesh. It is also possible to change position of multiple vertices at the same time, thus reducing the possibility of errors when altering the mesh.

Example:

 
changecom(//)changequote([,])
 
define(calc, [esyscmd(perl -e 'printf ($1)')])
 
define(VCOUNT, 0)
 
define(vlabel, [[// ]Vertex $1 = VCOUNT define($1, VCOUNT)define([VCOUNT], incr(VCOUNT))])
 
 
define(hex2D, hex ($1b $2b $3b $4b $1t $2t $3t $4t))
 
define(quad2D, ($1b $2b $2t $1t))
 
define(frontQuad, ($1t $2t $3t $4t))
 
define(backQuad, ($1b $4b $3b $2b))

The first four line of codes simply define a calculator, sets a variable VCOUNT = 0 and defines a new way of defining vertices. The last four are for defining 2D cells, as well as patches for the boundaries. The b is short for the bottom and t for top, that is the bottom and top of the 2D cell set.

So imagine we want to create a 2D channel with an inlet outlet and wall boundary conditions, first off we define the coordinates of the channel:

 
define(side, 100.0)
define(height, 300.0)
define(nrcellsx, 10)
define(nrcellsy, 30)
define(origox, 0.0)
define(origoy, 0.0)
define(coordinatesidex, calc(origox+side))
define(coordinatesidey, calc(origoy+height))
 
define(Z1, 0.0)
define(Z2, 1.0)

Then we want to define the actual vertices:

 
 
 
vertices
    (
    (origox origoy Z1) vlabel(a1b)
    (coordinatesidex origoy Z1) vlabel(a2b)
    (coordinatesidex coordinatesidey Z1) vlabel(a3b)
    (origox coordinatesidey Z1) vlabel(a4b)
 
    (origox origoy Z2) vlabel(a1t)
    (coordinatesidex origoy Z2) vlabel(a2t)
    (coordinatesidex coordinatesidey Z2) vlabel(a3t)
    (origox coordinatesidey Z2) vlabel(a4t)
    )

We can now define the block:

 
blocks
(
    // block0
    hex2D(a1, a2, a3, a4)
    (nrcellsx nrcellsy 1)
    simpleGrading (1 1 1)
);
 

Then, the boundary conditions is simply:

 
patches
 
(
    patch inlet
    (
	quad2D(a1,a2)
    )
 
    patch outlet
    (
	quad2D(a3,a4)
    )	
 
    empty back
    (
	backQuad(a1,a2,a3,a4)
    )
 
    empty front
    (
	frontQuad(a1,a2,a3,a4)
    )
 
    wall
    wall
    (
	quad2D(a1,a4)
	quad2D(a2,a3)
    )
);
 

When the file is finished, assuming it's called blockMeshDict.m4, one simply types

m4 blockMeshDict.m4 > blockMeshDict

Before running blockMesh as usual.