# 4.1.2. Aprepro Scripting

Fuego input files can use Aprepro commands to do pre-processing, calculations, and variable management within the input file itself. If you have an input file with Aprepro commands, you can choose to manually run Aprepro on that file to generate a processed output file like this

    aprepro myfile.in > myfile.out

However, this is not necessary. When running Fuego it will automatically run Aprepro on the input before parsing it, and the input file contents put in the header of the log file will be the Aprepro-resolved contents.

This section covers basic Aprepro usage as is relevant to general Fuego use. The complete Aprepro manual can be found with the SEACAS Documentation.

## 4.1.2.1. Defining Constants

An Aprepro constant can be declared inside `{}` anywhere in the input file. Aprepro constants cannot be re-defined later unless they are marked as mutable by using a leading underscore in their name. Aprepro constants can also be defined from the command line when calling Aria. The values supplied at the command line will override values in the input file. Multiple values should be separated with commas or spaces.

    fuego -i myfile.i --define "N=4"
    fuego -i myfile.i --define "N=4 M=2"
    fuego -i myfile.i --define "N=4,M=2"

When the input file is processed by Aprepro, the contents of the `{}` sections will be replaced with their values. For example, the following input

    # Tref = { Tref = 300 } K
    IC for Temperature on all_blocks = constant value = {Tref}
    BC Flux for Energy on surface_1 = Nat_Conv T_ref={Tref} h=5

would evaluate to this (which would be shown in the log file)

    # Tref = 300 K
    IC for Temperature on all_blocks = constant value = 300
    BC Flux for Energy on surface_1 = Nat_Conv T_ref=300 h=5

Note

While the line `Tref = {Tref = 300} K` may appear redundant in the input, since the term inside the `{}` is replaced with its actual value, using descriptive labels outside the `{}` results in a more readable output in the log file.

You can also do math in Aprepro to define functional values, for example to evaluate a correlation to get a convection coefficient you could use Aprepro like this

    # Tref = { Tref = 300 } K
    # D = { D = 0.1 } m
    # nu = { nu = 1e-5 } m2/s
    # V = { V = 10 } m/s
    # Re = { Re = V*D/nu }
    # Pr = { Pr = 0.7 }
    # k = { k = 0.05 } W/m-K
    # Nu = { Nu = 0.332*Re^0.5*Pr^(1/3) }
    # h = { h = Nu*k/D } W/m2-K

    BC Flux for Energy on surface_1 = Nat_Conv T_ref={Tref} h={h}

## 4.1.2.2. Including Files

Aprepro can also be used to separate your input into multiple files, which can help with readability and maintainability of your problem setup. For example, you could have a file with your commonly used Fuego user functions that is shared between multiple input setups. You can also put verbose sections of the input file into a separate file to keep the primary file more readable, especially for problems with a large number of blocks. For example:

    #{include("my_user_functions.inc")}

## 4.1.2.3. If-Else Logic

Aprepro allows the use of `if-else` statements, which can be used to conditionally activate parts of your input file. Commands inside a conditional statement will only be included in the actual Fuego input if the condition is true.

    # Use wall temperature = { use_wall_temp = 1 }
    # Do output = { do_output = 0 }

    {if(use_wall_temp)}
    wall_temperature = 500
    {else}
    # using an adiabatic wall
    {endif}

    {if(do_output)}
    Begin Results Output Foo
      # ...
    End
    {endif}

## 4.1.2.4. Loops

Aprepro also allows you to define simple loops, which can be helpful when having to repeat very similar commands many times in an input file. For example, if you want to generate an N by M grid of temperature probes you could do

    # M = { M = 10 }
    # N = { N = 15 }
    # x0 = { x0 = 0.1 }
    # y0 = { y0 = 0.2 }
    # dx = { dx = 0.1 }
    # dy = { dy = 0.1 }

    {NOECHO} { _i = 0 }
    {loop(M)}
    {NOECHO} {++_i} { _j = 0 }
    {loop(N)}
    {NOECHO} {++_j}
    {ECHO} # Tprobe_{_i}_{_j}
    Begin postprocess point
       Location = {x0 + (_i-1)*dx} {y0 + (_j-1)*dy} 0
       Output Name = Tprobe_{_i}_{_j}
       Function = "temperature"
    End
    {endloop}
    {endloop}

Which will generate 150 data probe commands in the input file. You could use similar logic to put those probe variables in the results output or heartbeat output block, which avoids boilerplate and makes it easy to change the probe grid location or resolution. The `{NOECHO}` and `{ECHO}` commands turn off and on output to the input file, respectively, and can be used to prevent intermediate output from being printed to the input file.

A similar approach can be used with delimited lists of parameters, such as boundary surfaces. If you had a list of surfaces, each of which needed a wall boundary condition with a different temperature, you could avoid repeating a nearly identical BC block N times using this approach by combining the list of surfaces with a list of wall temperatures.

    # wall surfaces = { wall_surfs = "surface_1 surface_2 surface_3 surface_4" }
    # wall temperatures = { wall_temps = "300 350 400 450" }

    {NOECHO} { _j = 0 } { num_wall_bcs = word_count(wall_surfs, " ") }
    {loop(num_wall_bcs)}
    {ECHO}# Wall BC { ++_j}
    Begin Wall Boundary Condition {get_word(_j, wall_surfs, " ")}
      wall temperature =  {get_word(_j, wall_temps, " ")}
    End
    {endloop}