Chi-Tech
Tutorial_01_DiffusionSim.h
Go to the documentation of this file.
1/** \page Tutorial01 Tutorial 1: Basic Diffusion Simulation
2
3 Let us tackle the basic diffusion equation as applied to steady state heat
4 transfer on a 3D orthogonal mesh.\n
5 \f[
6 -\nabla \cdot k \nabla T = q
7 \f]
8
9 The purpose of this tutorial is to understand the basics of the
10 input paradigm which is completely different from the traditional
11 input-card based method.
12 ChiTech uses an imbedded Lua console. For a history of Lua please see its
13 wikipedia page
14 <a href="https://en.wikipedia.org/wiki/Lua_(programming_language)">here</a>.
15 This paradigm allows the user to control many aspects of the program flow
16 as well to be more versatile when creating inputs, i.e. reading files, for
17 loops to create multiple entities etc. So let us get started.
18
19 ## Step 1 - Create your input file, open it in a text editor
20
21 Go to the directory of your
22 choosing and make an input file of your choosing. The input file does not
23 require a specific .lua or .inp extension although if you use .lua then
24 there are many
25 text editors that will be able to provide syntax highlighting.
26
27## Step 2 - Create a mesh handler
28
29\code
30chiMeshHandlerCreate()
31\endcode
32
33This function call creates a new mesh handler and pushes it to a global
34stack. It also make the newly created handler the "current" meaning all
35 mesh operations will operate on this handler.
36 The concept of creating, reading or manipulating computational meshes is
37centered on operating on a specific chi_mesh::MeshHandler object. Physics/math
38 objects can then freely operate on meshes by simply specifying which handler
39 to use.
40
41## Step 3 - Create a 3D mesh
42
43 For this we will create a simple orthogonal grid of 32x32x32 cells
44 (32,768 total) as shown in Figure 1.
45
46
47 \image html "Meshing/CubeMeshTut1.png" "Figure 1 - Mesh spanning from [-1,-1,-1] to [1,1,1]" width=350px
48
49The first step of this process is to define an array of nodes starting from -1.0
50with a distance \f$ ds \f$ between each of them. In lua we can create this array
51programatically:
52\code
53nodes={}
54N=32
55ds=2.0/N
56for i=0,N do
57 nodes[i+1] = i*ds
58end
59\endcode
60
61Note here that lua arrays cannot use `nodes[0]` since arrays in lua are not
62zero based. The next step is call chiMeshCreateUnpartitioned3DOrthoMesh with
63the node arrangement along the X-direction, Y-direction and Z-direction,
64which in our case is the same,
65
66\code
67surf_mesh, region1 = chiMeshCreateUnpartitioned3DOrthoMesh(nodes,nodes,nodes)
68\endcode
69
70Some work has been encapsulated behind the scenes here. Firstly, a 2D surface
71mesh was created and assigned to a region.
72Secondly a surface-mesher (chi_mesh::SurfaceMesher)
73 and a volume mesher (chi_mesh::VolumeMesher) has been
74assigned to the mesh handler. The volume mesher is not executed because the
75macro allows the user to first assign parallel partitioning.
76
77## Step 4 - Executing the mesher
78The underlying mesher for a 3D mesh is an extruded mesh from 2D. This mesh
79 has some partitioning properties that can be set to allow parallel simulations,
80 however, we will just focus on serial simulations for now.
81 The next step to complete meshing is to execute the volume mesher. Since we
82 are not going to set any partitioning parameters we will just execute it now.
83
84\code
85chiVolumeMesherExecute();
86\endcode
87
88## Step 5 - Assign material- and boundary IDs and
89
90Materials ID's can conveniently be specified using logical volumes. There are
91many options for logical volumes ranging from primitive parametric surfaces
92 to non-convex user generated surfaces using surface meshes
93 (see chiLogicalVolumeCreate). For this tutorial
94 we will use a rectangular paralellipiped (RPP or brick) as follows.
95
96\code
97material = chiPhysicsAddMaterial("Test Material");
98
99vol0 = chiLogicalVolumeCreate(RPP,-1000,1000,-1000,1000,-1000,1000)
100chiVolumeMesherSetProperty(MATID_FROMLOGICAL,vol0,material)
101\endcode
102
103We first create a material using the chiPhysicsAddMaterial() function.
104 The handle of this material will essentially be zero but it is not technically
105 required by the chiVolumeMesherSetProperty() function since this function
106 operates on the integer supplied.
107This material is added to the physics environment and therefore has scope over
108all mesh handlers and all physics entities. We then create a logical volume
109 using the function chiLogicalVolumeCreate() with arguments RPP,
110 specifying that we will be using a Rectangular Parallelipiped and then a
111 series of dimensions specifying xmin-xmax-ymin-ymax-zmin-zmax. Every cell
112 centroid within these dimensions will be flagged as being "within" the logical
113 volume.
114
115Actually setting the mesh's material id's is a utility facilitated by a
116 volume mesher property and hence we call chiVolumeMesherSetProperty()
117 with a property index MATID_FROMLOGICAL. Next we provided a handle to the
118 logical volume (vol0) and the desired material id. Logical volumes are very
119 diverse and their uses are discussed elsewhere. There is an additional utility,
120 chiVolumeMesherSetMatIDToAll(), which will set all cell-material-ids without
121 requiring a logical volume, however, in this tutorial we opted to show the
122 logical volume route.
123
124### Boundary IDs
125By default all boundaries are unassigned (i.e., -1). There are two utilities
126 that set the boundary id's the first of which is essentially identical to how
127 material ids are set, chiVolumeMesherSetProperty(), but this time the property
128 index is BNDRYID_FROMLOGICAL. The second way is to use
129 chiVolumeMesherSetupOrthogonalBoundaries() which requires no arguments and will
130 asssign standard indices to a boundary if it is aligned with the orthogonal
131 cartesian directions.
132
133The culmination of this step is all done within a physics agnostic framework.
134The user can even export the mesh for visualization using the function
135 chiMeshHandlerExportMeshToObj().
136
137### Boundary IDs
138
139
140## Step 5 - Adding material properties
141
142Now that the cells have been assigned a material id we need to add
143 properties to the material conducive to a diffusion simulation. For a heat
144 transfer diffusion simulation we will need to know the thermal conductivity
145 "k" and the volumetric source strength "q". Both of these can be simple
146 scalar values.
147
148\code
149chiPhysicsMaterialAddProperty(material,SCALAR_VALUE,"k")
150chiPhysicsMaterialSetProperty(material,"k",SINGLE_VALUE,1.0)
151
152chiPhysicsMaterialAddProperty(material,SCALAR_VALUE,"q")
153chiPhysicsMaterialSetProperty(material,"q",SINGLE_VALUE,1.0)
154\endcode
155
156In this code we created the material properties using the function
157 chiPhysicsMaterialAddProperty() which requires a handle to the reference
158 material, the property type (SCALAR_VALUE), and a name for the property.
159 Unlike extrusion layers the property name can be used in further calls to refer
160 to the specific property.
161
162Material property values are set using the function
163 chiPhysicsMaterialSetProperty() which again expects a handle to the
164 reference material, then either a material property id or name (in this case
165 name), then an operation index and value(s). For this case we used an operation
166 index SINGLE_VALUE which is the only operation supported by SCALAR_VALUE. In
167 future the user can specify, as an example, temperature dependent values which
168 will support the operation FROM_TABLE, but that is a topic for a different time.
169
170## Step 6 - Setup the diffusion physics
171
172The following sequence of function calls completely define the diffusion solver.
173
174\code
175phys1 = chiDiffusionCreateSolver()
176chiSolverSetBasicOption(phys1,"discretization_method","PWLC")
177chiSolverSetBasicOption(phys1,"residual_tolerance",1.0e-6)
178\endcode
179
180We first create the diffusion solver with a call to
181 chiDiffusionCreateSolver(). This creates the solver and pushes it onto
182 the physics handler. The function returns the handle.
183
184Next we can set numerous diffusion solver properties which can comprehensively
185 be viewed in its specific documentation (chiDiffusionSetProperty()).
186
187## Step 7 - Initialize and Solve
188
189The final step of this process is to initialize and execute the diffusion solver.
190
191\code
192chiDiffusionInitialize(phys1)
193chiDiffusionExecute(phys1)
194\endcode
195
196## Step 8 - Post-processing
197The execution of a Chi-Tech physics module culminates in the creation of one or
198 more field functions. These field functions should all be populated for use
199 during the initialization phase of the solver. Users can get handles to all
200 the field functions by using the chiGetFieldFunctionList call. Thereafter, the
201 field function can be exported to VTK-format which can be read by Paraview.
202
203\code
204fflist,count = chiGetFieldFunctionList(phys1)
205chiExportFieldFunctionToVTK(fflist[1],"Tutorial1Output","Temperature")
206\endcode
207
208
209
210## Complete input file
211
212Here is the complete input file with comments
213
214\code
215--############################################### Setup mesh
216chiMeshHandlerCreate()
217
218nodes={}
219N=32
220ds=2.0/N
221for i=0,N do
222 nodes[i+1] = -1.0 + i*ds
223end
224surf_mesh,region1 = chiMeshCreateUnpartitioned3DOrthoMesh(nodes,nodes,nodes)
225
226chiVolumeMesherExecute();
227
228material = chiPhysicsAddMaterial("Test Material");
229
230-- Set Material IDs
231vol0 = chiLogicalVolumeCreate(RPP,-1000,1000,-1000,1000,-1000,1000)
232chiVolumeMesherSetProperty(MATID_FROMLOGICAL,vol0,material)
233
234chiMeshHandlerExportMeshToVTK("Mesh")
235--############################################### Add material properties
236
237
238-- Set material properties
239chiPhysicsMaterialAddProperty(material,SCALAR_VALUE,"k")
240chiPhysicsMaterialSetProperty(material,"k",SINGLE_VALUE,1.0)
241
242chiPhysicsMaterialAddProperty(material,SCALAR_VALUE,"q")
243chiPhysicsMaterialSetProperty(material,"q",SINGLE_VALUE,1.0)
244
245
246--############################################### Setup Physics
247phys1 = chiDiffusionCreateSolver()
248chiSolverSetBasicOption(phys1,"discretization_method","PWLC");
249chiSolverSetBasicOption(phys1,"residual_tolerance",1.0e-6)
250
251--############################################### Initialize and
252-- Execute Solver
253chiDiffusionInitialize(phys1)
254chiDiffusionExecute(phys1)
255
256----############################################### Visualize the field function
257fflist,count = chiGetFieldFunctionList(phys1)
258chiExportFieldFunctionToVTK(fflist[1],"Tutorial1Output","Temperature")
259\endcode
260
261
262## Step 9 - Execute the code
263Assuming you added the executable to your PATH environment variable, the code
264can be executed by typing the executable name followed by the input file path
265 (relative or absolute).
266
267\verbatim
268ChiTech Tutorial01.lua
269\endverbatim
270
271The output produced will look as follows:
272
273\verbatim
274[0] Parsing argument 1 Tutorials/Tutorial01.lua
275[0] 2022-05-09 14:01:21 Running ChiTech in batch-mode with 1 processes.
276[0] ChiTech number of arguments supplied: 1
277[0] Computing cell-centroids.
278[0] Done computing cell-centroids.
279[0] Checking cell-center-to-face orientations
280[0] Done checking cell-center-to-face orientations
281[0] 00:00:00 Establishing cell connectivity.
282[0] 00:00:00 Vertex cell subscriptions complete.
283[0] 00:00:00 Surpassing cell 3277 of 32768 (10%)
284[0] 00:00:00 Surpassing cell 6554 of 32768 (20%)
285[0] 00:00:00 Surpassing cell 9831 of 32768 (30%)
286[0] 00:00:00 Surpassing cell 13108 of 32768 (40%)
287[0] 00:00:00 Surpassing cell 16384 of 32768 (50%)
288[0] 00:00:00 Surpassing cell 19661 of 32768 (60%)
289[0] 00:00:00 Surpassing cell 22938 of 32768 (70%)
290[0] 00:00:00 Surpassing cell 26215 of 32768 (80%)
291[0] 00:00:00 Surpassing cell 29492 of 32768 (90%)
292[0] 00:00:00 Surpassing cell 32768 of 32768 (100%)
293[0] 00:00:00 Establishing cell boundary connectivity.
294[0] 00:00:00 Done establishing cell connectivity.
295[0] 00:00:00 VolumeMesherPredefinedUnpartitioned executing. Memory in use = 61 MB
296[0] Computed centroids
297[0] Partitioning mesh with ParMETIS.
298[0] Done partitioning mesh.
299[0] Cells loaded.
300[0] VolumeMesherPredefinedUnpartitioned: Cells created = 32768
301[0] 00:00:00 chiVolumeMesherExecute: Volume meshing completed. Memory used = 43.5 MB
302[0] Total process memory used after meshing 104 MB
303[0] 00:00:00 Setting material id from logical volume.
304[0] 00:00:00 Done setting material id from logical volume. Number of cells modified = 32768.
305[0] Exporting mesh to VTK. 32768
306[0] Done exporting mesh to VTK.
307[0] Solver:DiffusionSolver option:discretization_method set to PWLC.
308[0] Solver:DiffusionSolver option:residual_tolerance set to 1e-06.
309[0]
310[0] 00:00:00 DiffusionSolver: Initializing Diffusion solver
311[0] Identifying unique boundary-ids.
312[0] Max boundary id identified: 0
313[0] 00:00:00 Creating Piecewise Linear Continuous Finite Element spatial discretizaiton.
314[0] 00:00:08 Developing nodal ordering.
315[0] 00:00:08 Done creating Piecewise Linear Continuous Finite Element spatial discretizaiton.
316[0] DiffusionSolver: Global number of DOFs=35937
317[0] Building sparsity pattern.
318[0] 00:00:09 DiffusionSolver: Diffusion Solver initialization time 8.76791
319[0] Setting matrix preallocation.
320[0] 00:00:09 DiffusionSolver: Assembling A locally
321[0] 00:00:09 DiffusionSolver: Done Assembling A locally
322[0] 00:00:09 DiffusionSolver: Communicating matrix assembly
323[0] 00:00:09 DiffusionSolver: Assembling A globally
324[0] 00:00:09 DiffusionSolver: Diagonal check
325[0] Number of mallocs used = 0
326[0] Number of non-zeros allocated = 912673
327[0] Number of non-zeros used = 759717
328[0] Number of unneeded non-zeros = 152956
329[0] 00:00:09 DiffusionSolver: Assembling x and b
330[0] 00:00:09 DiffusionSolver: Solving system
331[0] Diffusion iteration 0 - Residual 2.6521952e+02
332[0] Iteration 0 Residual 265.22
333[0] Diffusion iteration 1 - Residual 3.1006314e+01
334[0] Iteration 1 Residual 31.0063
335[0] Diffusion iteration 2 - Residual 4.0467718e+00
336[0] Iteration 2 Residual 4.04677
337[0] Diffusion iteration 3 - Residual 4.9168004e-01
338[0] Iteration 3 Residual 0.49168
339[0] Diffusion iteration 4 - Residual 5.5399485e-02
340[0] Iteration 4 Residual 0.0553995
341[0] Diffusion iteration 5 - Residual 7.3128018e-03
342[0] Iteration 5 Residual 0.0073128
343[0] Diffusion iteration 6 - Residual 1.3610040e-03
344[0] Iteration 6 Residual 0.001361
345[0] Diffusion iteration 7 - Residual 1.7105415e-04
346[0] Iteration 7 Residual 0.000171054
347[0] Diffusion iteration 8 - Residual 2.2641339e-05
348[0] Iteration 8 Residual 2.26413e-05
349[0] Diffusion iteration 9 - Residual 3.3728166e-06
350[0] Iteration 9 Residual 3.37282e-06
351[0] Diffusion iteration 10 - Residual 3.1009104e-07
352[0] Iteration 10 Residual 3.10091e-07
353[0] Convergence reason: KSP_CONVERGED_RTOL
354[0] 00:00:09 DiffusionSolver[g=0-0]: Number of iterations =10
355[0] Timing:
356[0] Assembling the matrix: 0.085187
357[0] Solving the system : 0.075084
358[0] Diffusion Solver execution completed!
359[0] Exporting field function phi to files with base name Tutorial1Output
360[0] Final program time 00:00:10
361[0] 2022-05-09 14:01:32 ChiTech finished execution of Tutorials/Tutorial01.lua
362\endverbatim
363
364\image html "Meshing/CubeSolutionTut1.png" "Figure 2 - Solution viewed in Paraview" width=700px
365
366
367 */