Step 2: Write an Input File

In this step, the concept of an input file is introduced. These files provide the means for controlling finite element (FE) simulations with MOOSE. To demonstrate this concept, a steady-state diffusion of pressure from one end of the pipe, between the pressure vessels, to the other (see the Problem Statement page) will be considered. The goal, here, is to create an input file that solves this simple boundary value problem (BVP). This problem is detailed in the Demonstration section, but, first, some basic information regarding input files and their execution are provided. As for many steps of this tutorial, concepts will be introduced and a hands-on demonstration will follow.

Input File Format

MOOSE input files use a .i extension and are formatted using the Hierarchical Input Text (HIT) format, which is a nested block structure. By convention, blocks beginning with capital letters are syntax that is dictated by the application. Blocks starting with lower case letters are arbitrary names assigned by the creator of the input file. A complete list of the available syntax and the associated objects for MOOSE-based applications is available on the Complete Syntax page.

To demonstrate this format, consider a C++ class designed to model the diffusion of some field variable . An object, or a single instance of this class, is invoked in an input file by the following syntax:

[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>]
  [diff]
    type = Diffusion<<<{"description": "The Laplacian operator ($-\\nabla \\cdot \\nabla u$), with the weak form of $(\\nabla \\phi_i, \\nabla u_h)$.", "href": "../../../source/kernels/Diffusion.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = u
  []
[]

The syntax type = Diffusion denotes the C++ class that is named Diffusion and is capable of solving the Laplace operator, also commonly referred to as the diffusion term.

Within each sub-block, any number of name/value pairs are provided, and these correspond to the parameters required for the given class. Although there are usually several input parameters required, Diffusion does not need any except the variable for which to operate on. Variables also have their own block in input files. At the very least, a MOOSE input file requires the following six block types:

  • [Mesh]: Define the geometry of the domain

  • [Variables]: Define the unknown(s) of the problem

  • [Kernels]: Define the equation(s) to solve

  • [BCs]: Define the boundary condition(s) of the problem

  • [Executioner]: Define how the problem will solve

  • [Outputs]: Define how the solution will be written

It should be obvious that a basic FE analysis problem requires a mesh, variables, equations, and boundary conditions. Also, methods to handle the numerical solve and record its results are necessary, so the [Executioner] and [Outputs] blocks are required for these purposes.

schooltip:Block types

The names of blocks suggest what types of objects can be used within those blocks and the tasks they perform. Please visit the Syntax Documentation page for a complete list of available syntax and associated objects.

For more information about input files, please visit the Input File Syntax page.

Execute an Input File

There are a several ways to execute an input file—a couple of which shall be explained here. From Step 1, the reader should have already created an executable for their application, but, if not, be sure to run the following commands:

cd ~/projects/babbler
make -j4

Execute Using the Terminal

The most basic way to execute an input file is from a terminal. To do this, a user may navigate to the directory where their input file is stored and then pass it to the executable with the -i argument. For example, the input file for the application's default test may be executed as follows:

cd ~/projects/babbler/test/tests/kernels/simple_diffusion
../../../../babbler-opt -i simple_diffusion.i

The input file could also be executed relative to the application's root directory:

cd ~/projects/babbler
./babbler-opt -i test/tests/kernels/simple_diffusion/simple_diffusion.i

The application will run the FE simulation and populate the directory with all of the requested outputs, e.g., ExodusII or comma delimited files. Here, a file called simple_diffusion_out.e should have been created. As mentioned in Helpful Software, this file can be opened to visualize results of the solution with ParaView or Peacock (the MOOSE in-house graphical user interface (GUI)).

Execute Using Peacock

Peacock provides a second way to execute an input file. To demonstrate this, run the following commands:

cd ~/projects/babbler/test/tests/kernels/simple_diffusion
~/projects/moose/python/peacock/peacock -i simple_diffusion.i

This will open the Peacock window and display the mesh used for the simple diffusion test. To execute the input file, click on the "Execute" tab and then click "Run". Once the solve completes, click on the "ExodusViewer" tab to view the results.

warningwarning:First execution of Peacock is slow

Peacock is a python application. As such, during the initial execution binary files are cached, which often takes a few minutes. Subsequent executions of Peacock should be quicker.

commentnote:Bash alias for Peacock

The command-line syntax for running Peacock can be simplified by creating a bash alias for it. Be sure to visit the Peacock page to learn how to do this.

Demonstration

The Laplace equation shall be employed to model the steady-state diffusion of pressure on the domain . Thus, find such that

(1)

satisfies the following BVP: at the inlet (left) boundary, at the outlet (right) boundary, and , where is the surface normal vector, on the remaining boundaries.

Input File

In this section, the setup of an input file to model the steady-state diffusion of pressure over the length of the pipe will be detailed. To begin, create a directory named "problems:"

cd ~/projects/babbler
mkdir problems

Next, use a text editor to create a file named pressure_diffusion.i in the problems directory. This file is where the block-structured (HIT) format will be used to setup the inputs needed to solve the given BVP.

commentnote:Block order doesn't matter.

The blocks need not be listed in any particular order within the input file.

Recall that six basic blocks—those which were mentioned in the Input File Format section—are required. For the [Mesh] block, the geometry of the pipe, whose dimensions were provided on the Problem Statement page, shall be defined using the MOOSE standard rectilinear mesh generator object, GeneratedMesh:

[Mesh<<<{"href": "../../../syntax/Mesh/index.html"}>>>]
  type = GeneratedMesh # Can generate simple lines, rectangles and rectangular prisms
  dim = 2 # Dimension of the mesh
  nx = 100 # Number of elements in the x direction
  ny = 10 # Number of elements in the y direction
  xmax = 0.304 # Length of test chamber
  ymax = 0.0257 # Test chamber radius
[]

This creates a planar mesh with a height equal to the pipe radius. Thus, this problem shall be solved using cylindrical coordinates. To do this, a [Problem] block shall be included in addition to the basic six blocks:

[Problem<<<{"href": "../../../syntax/Problem/index.html"}>>>]
  type = FEProblem # This is the "normal" type of Finite Element Problem in MOOSE
  coord_type = RZ # Axisymmetric RZ
  rz_coord_axis = X # Which axis the symmetry is around
[]

The purpose of this block is to indicate that the planar mesh represents an axisymmetric body defined with respect to a cylindrical coordinate system.

The pressure variable shall be added to the [Variables] block with an unambiguous name, i.e., pressure:

[Variables<<<{"href": "../../../syntax/Variables/index.html"}>>>]
  [pressure]
    # Adds a Linear Lagrange variable by default
  []
[]

The variables listed here are the variables to be solved for using the FEM. Next, the [Kernels] block, whose syntax was demonstrated earlier, shall be included. Here, the ADDiffusion class will be used to solve Eq. (1) and the pressure variable will be operated on:

[Kernels<<<{"href": "../../../syntax/Kernels/index.html"}>>>]
  [diffusion]
    type = ADDiffusion<<<{"description": "Same as `Diffusion` in terms of physics/residual, but the Jacobian is computed using forward automatic differentiation", "href": "../../../source/kernels/ADDiffusion.html"}>>> # Laplacian operator
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = pressure # Operate on the "pressure" variable from above
  []
[]

Now that the domain , the primary variable , and the PDE have been specified, the BVP must be enforced. The ADDirichletBC class enforces a Dirichlet (essential) boundary condition, e.g., the pressures prescribed at the pipe inlet and outlet. For this problem, two separate ADDirichletBC objects are setup under the [BCs] block—one for each end of the pipe:

[BCs<<<{"href": "../../../syntax/BCs/index.html"}>>>]
  [inlet]
    type = ADDirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/ADDirichletBC.html"}>>> # Simple u=value BC
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = pressure # Variable to be set
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = left # Name of a sideset in the mesh
    value<<<{"description": "Value of the BC"}>>> = 4000 # (Pa) From Figure 2 from paper. First data point for 1mm spheres.
  []
  [outlet]
    type = ADDirichletBC<<<{"description": "Imposes the essential boundary condition $u=g$, where $g$ is a constant, controllable value.", "href": "../../../source/bcs/ADDirichletBC.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = pressure
    boundary<<<{"description": "The list of boundary IDs from the mesh where this object applies"}>>> = right
    value<<<{"description": "Value of the BC"}>>> = 0 # (Pa) Gives the correct pressure drop from Figure 2 for 1mm spheres
  []
[]

It is not necessary to enforce the Neumann (natural) boundary conditions, , since they are zero-valued fluxes.

The problem being solved does not have a time component, so a steady-state executioner object, Steady, is invoked to solve the resulting equation:

[Executioner<<<{"href": "../../../syntax/Executioner/index.html"}>>>]
  type = Steady # Steady state problem
  solve_type = NEWTON # Perform a Newton solve

  # Set PETSc parameters to optimize solver efficiency
  petsc_options_iname = '-pc_type -pc_hypre_type' # PETSc option pairs with values below
  petsc_options_value = ' hypre    boomeramg'
[]

Finally, the computed FE solution shall be output in ExodusII format by adding the following syntax for the [Outputs] block:

[Outputs<<<{"href": "../../../syntax/Outputs/index.html"}>>>]
  exodus<<<{"description": "Output the results using the default settings for Exodus output."}>>> = true # Output Exodus format
[]

There are a lot of ways to control the solution when using the Steady class (or the Transient class for time-dependent simulations). For instance, the parameters which set the PETSc solver options can be very influential on the convergence rate of the NEWTON solve. Throughout this tutorial, the reader is encouraged to test different combinations of input parameters, especially for Executioner objects. After running the input file, as it was given here, the reader may remove the PETSc options parameters, run it again, and observe the difference in the convergence rate.

Results

In Execute an Input File, some ways in which to execute and visualize the results of an input file were discussed. These methods should be reviewed to find a preferred means of interacting with the application. As a reminder, the pressure_diffusion.i file can be executed from the terminal by entering the following:

cd ~/projects/babbler/problems
../babbler-opt -i pressure_diffusion.i

If the input file was ran from the terminal, and the pressure_diffusion_out.e file exists, the results can be rendered in Peacock by running the following commands:

cd ~/projects/babbler/problems
~/projects/moose/python/peacock/peacock -r pressure_diffusion_out.e

After running the above commands, the Peacock window opens to the "ExodusViewer" tab and a result which resembles that shown in Figure 1 will be displayed.

Figure 1: Rendering of the FEM solution of Eq. (1) subject to the given BVP.

Notice that the FEM solution depicted in Figure 1 satisfies the boundary conditions, i.e., a pressure of 4000 Pa can be observed at the inlet and zero pressure at the outlet. The pressure distribution over the length of the pipe also appears to be uniform across its radius, indicating that there is no flux through any of the remaining boundaries. Thus, is also satisfied at those boundaries.

Commit

A GitHub repository to store the new MOOSE-based application was created as part of the previous step of this tutorial. The repository should also contain the first commit to the origin remote (the online copy). Now that a new file exists in the local repository, i.e., problems/pressure_diffusion.i, and since this input file has been verified to produce good results, it should be committed and pushed to the remote. Before proceeding, inspect the status of the local repository as it compares to the HEAD, which denotes the version that existed following the most recent commit:

cd ~/projects/babbler
git status

The terminal output should read something like the following:

On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	problems/

nothing added to commit but untracked files present (use "git add" to track)

This indicates that a new directory problems has not been staged, and that there may or may not be more unstaged files in that directory. Of course, in this case, there are. Proceed with the instructions provided in the output for adding the new files and then reinspect the status of the local repository:

git add problems
git status

Now, the terminal output should be the following:

On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	new file:   problems/pressure_diffusion.i

To commit these changes, simply enter git commit. A user will then be prompted to enter a message describing the changes. For this change, the message added might be "created an input file to solve diffusion problem," as shown in the example below.

created an input file to solve diffusion problem
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Your branch is up to date with 'origin/main'.
#
# Changes to be committed:
#       new file:   problems/pressure_diffusion.i
#

After exiting the git commit prompt, simply enter git push to update the origin remote. The remote repository on github.com/YourGitHubUserName/babbler can be inspected to confirm that the changes have been published.

schooltip:Interacting with Git

As mentioned in Step 1, there are a lot of ways to interact with Git. There are even GUI applications for using Git—the terminal is not the only way. It is important to become comfortable with this approach to software development, especially for MOOSE application development.