4.4 NekMesh in NekPy

The Python interface allows the user to instantiate input, output, and process modules by calling the static Create method of the InputModule, ProcessModule, and OutputModule, register configuration options, and process them. Consider the following example:

1import sys 
2from NekPy.NekMesh import Mesh, ProcessModule, OutputModule 
3 
4mesh = Mesh() 
5mesh.expDim = 3 
6mesh.spaceDim = 3 
7mesh.nummode = 5 
8mesh.verbose = True 
9 
10# Load the CAD file 
11ProcessModule.Create("loadcad", mesh, \ 
12               filename="input.stp", verbose=True).Process() 
13# Load the octree 
14ProcessModule.Create("loadoctree", mesh, mindel=0.04,\ 
15                maxdel=0.2, eps=0.02).Process() 
16# Create a surface mesh 
17ProcessModule.Create("surfacemesh", mesh).Process() 
18# Output a 2D manifold mesh 
19mesh.expDim = 2 
20# Create a high-order surface 
21ProcessModule.Create("hosurface", mesh).Process() 
22# Dump out elemental Jacobians 
23ProcessModule.Create("jac", mesh, list=True).Process() 
24# Dump out the surface mesh. 
25OutputModule.Create("xml", mesh, test=True,\ 
26               outfile="output.xml").Process()

After importing the Mesh, ProcessModule, and OutputModule classes, first we create a Mesh object by calling the constructor. This object will be shared by the modules. Then we manipulate the Mesh object by creating different ProcessModules, at the end we write out the result into a xml file using an OutputModule. The configuration options for a given module are passed to the static Create method of the InputModule, ProcessModule, and OutputModule. This creates the corresponding module and the modules can be processed immediately after instantiation. Note that the first parameter of the Create method has to be the key for a given module, the second is the previously created Mesh object. The remaining keyword arguments can specify additional parameters for a module.

The Python interface allows the user to create new modules by inheriting from one of the possible base classes (InputModule, ProcessModule, OutputModule).

The following is a simple example when we inherit from the InputModule and override the Process method:

1import sys 
2from NekPy.LibUtilities import ShapeType 
3import NekPy.NekMesh as NekMesh 
4import numpy as np 
5 
6# StructuredGrid creates a 2D structured grid of triangles. 
7class StructuredGrid(NekMesh.InputModule): 
8   def __init__(self, mesh): 
9      super(StructuredGrid, self).__init__(mesh) 
10      self.mesh.spaceDim = 2 
11      self.mesh.expDim = 2 
12      # Define some configuration options for this module. 
13      self.AddConfigOption("nx", "2", "Number of points in x direction") 
14      self.AddConfigOption("ny", "2", "Number of points in y direction") 
15      self.AddConfigOption("lx", "0", "Lower-left x-coordinate") 
16      self.AddConfigOption("rx", "0", "Upper-right x-coordinate") 
17      self.AddConfigOption("ly", "0", "Lower-left y-coordinate") 
18      self.AddConfigOption("ry", "0", "Upper-right y-coordinate") 
19      self.AddConfigOption("compid", "0", "Composite ID") 
20 
21   def Process(self): 
22      # Get the input variables from our configuration options. 
23      coord_1x = self.GetFloatConfig("lx") 
24      coord_1y = self.GetFloatConfig("ly") 
25      coord_2x = self.GetFloatConfig("rx") 
26      coord_2y = self.GetFloatConfig("ry") 
27      nx = self.GetIntConfig("nx") 
28      ny = self.GetIntConfig("ny") 
29      compID = self.GetIntConfig("compid") 
30      x_points = np.linspace(coord_1x, coord_2x, nx) 
31      y_points = np.linspace(coord_1y, coord_2y, ny) 
32 
33      nodes = [] 
34      id_cnt = 0 
35 
36      for y in range(ny): 
37         tmp = [] 
38         for x in range(nx): 
39            tmp.append(NekMesh.Node(id_cnt, x_points[x], y_points[y], 0.0)) 
40            id_cnt += 1 
41         nodes.append(tmp) 
42      self._create_triangles(nodes, nx, ny, compID) 
43      # Call the Module functions to create all of the edges, faces and 
44      # composites. 
45      self.ProcessVertices() 
46      self.ProcessEdges() 
47      self.ProcessFaces() 
48      self.ProcessElements() 
49      self.ProcessComposites() 
50 
51   def _create_triangles(self, nodes, nx, ny, compID): 
52      ... 
53 
54# Register our TestInput module with the factory. 
55NekMesh.Module.Register( 
56   NekMesh.ModuleType.Input, "StructuredGrid", StructuredGrid) 
57 
58if __name__ == ’__main__’: 
59   # Create a ’pipeline’ of the input and output modules. 
60   mesh = NekMesh.Mesh() 
61 
62   # First, call our input module’s create function from the NekMesh factory. 
63   NekMesh.InputModule.Create( 
64      "StructuredGrid", mesh, 
65      nx = sys.argv[1], ny = sys.argv[2], lx = sys.argv[3], 
66      ly = sys.argv[4], rx = sys.argv[5], ry = sys.argv[6], 
67      compid = sys.argv[7], shape = sys.argv[8]).Process() 
68 
69   # Then ensure there’s no negative Jacobians. 
70   NekMesh.ProcessModule.Create("jac", mesh, list=True).Process() 
71 
72   # Finally, output the resulting file 
73   NekMesh.OutputModule.Create( 
74      "xml", mesh, test=True, outfile=sys.argv[9]).Process()