4.1.2. Aprepro Scripting

Aria 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 Aria 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 Aria 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.

aria -i myfile.i --define "N=4"
aria -i myfile.i --define "N=4 M=2"
aria -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 Aria material definitions that is shared between multiple input setups. You can also put verbose sections of the input file like material assignment into a separate file to keep the primary file more readable, especially for problems with a large number of blocks. For example:

# Material Assignments (materials.inc)
Use material al_6061 for block_1
Use material al_6061 for block_2
Use material al_6061 for block_3
Use material ss_304 for block_4
Use material ss_304 for block_5
Use material ss_304 for block_6
Use material pmdi_foam for block_7
#{include("parameters.inc")}

Begin Finite Eleement Model foo
    #{include("materials.inc")}
End

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 Aria input if the condition is true.

# Use constant flux = { use_const_flux = 1 }
# Do output = { do_output = 0 }

{if(use_const_flux)}
BC Flux for energy on surface_1 = constant value = 1
{else}
BC Flux for Energy on surface_1 = Nat_Conv T_ref=300 h=10
{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} Postprocess value of expression temperature at location \$
       {x0 + (_i-1)*dx} {y0 + (_j-1)*dy} as Tprobe_{_i}_{_j}
{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 enclosure surfaces. If you had a list of surfaces, each of which needed an enclosure definition block, you could avoid repeating a nearly identical enclosure block N times using this approach.

# enclosure surfaces = { encl_surfs = "surface_1 surface_2 surface_3 surface_4" }

{NOECHO} { _j = 0 } { num_enclosures = word_count(encl_surfs, " ") }
{loop(num_enclosures)}
{ECHO}# Enclosure { ++_j}
Begin Enclosure Definition enc_{_j}
  Add Surface {get_word(_j, encl_surfs, " ")}
  Blocking Surfaces
  Use Viewfactor Calculation hemicube
  Use Viewfactor Smoothing none
  Use Radiosity Solver rs_gmres
End
{endloop}