Configuration file#
The general structure of the .yaml
configuration file is
simulations:
# Series of simulations
- name: SimulationName
# False if you don't wish to run the simulation
# Defaults to true
run_simul: true
# Number of time steps to run
n_steps: 50000
# Folder to use as base for saving output
save_path: "output/path/save"
# Frequency to report simulation status
report: {start_step: 0, end_step: 0, frequency: 1000}
# Domain's properties and specifications
domain: ...
# Data for export
data: ...
# Models to use
models: ...
# Another simulation in the same file
- name: AnotherSimulation
n_steps: 20000
save_path: "another/output/path/save"
report: {start_step: 0, end_step: 0, frequency: 1000}
domain: ...
data: ...
models: ...
Note
For a full example of a configuration, check the kitchensink.
It has a series of simulations, each one describing its configurations. Each simulation has, among other things, a name, that must be unique in the file, and three important fields:
These fields configure some important aspects that are described in their specific topics. But there are other very important fields and inside logic for the configuration file that we must explain first.
Parent simulation#
It’s very common to have two very similar simulations, that differs only in some configurations. Nassu supports using a parent simulation for that.
simulations:
# Parent simulation
- name: parentSimulation
...
# Simulation that inheritages values from parent
- name: childSimulation
parent: parentSimulation
...
# Key value to overwrite
key_to_overwrite: value
In this configuration, the child simulation inherits all configuration from the parent and overwrites only the specifics keys present in its configuration. The rules for overwriting are:
If the key in the child is a dicitonary and exists in the parent, it proceeds to check its dictionary keys
If the key in the child is a dicitonary and not exists in the parent, it adds this key to the configuration
If the key in the child is not a dictionary, it’s overwritten or added to the configuration
For example
simulations:
- name: parentSimulation
domain:
domain_size:
x: 16
y: 16
z: 32
bodies:
sphere:
...
- name: childSimulation
parent: parentSimulation
domain:
domain_size:
x: 32
bodies:
cube:
...
In this case the data.domain_size.x
will be overwritten in the child simulation, mantaining the y
and z
value the same.
For the data.bodies
field, the child simulation will have both the sphere
and the cube
as its keys.
Preveting inheritage (!not-inherit
)#
There are times when we want to inheritage most fields, but sometimes we don’t want to.
In the previous example, suppose we didn’t want the sphere
to be present in the child simulation.
Then we can use the !not-inherit
tag
simulations:
- name: parentSimulation
domain:
bodies:
sphere:
...
- name: childSimulation
parent: parentSimulation
domain:
bodies: !not-inherit
cube:
...
In this case it prevents any inheritage in the data.bodies
field, so that we have only the cube
in it.
This is very useful when you want to prevent just some specific fields of being inherited.
Simulation series (!unroll
)#
One common use case is when we want to make the same simulation, but just change some reference values or configuration.
Suppose that the only difference between two cases are the velocity, or the domain size in x, or the viscosity.
For these cases we use the !unroll
tag
simulations:
- name: mySimulation
models:
LBM:
tau: !unroll [0.51, 0.505]
F:
x: !unroll [1e-5, 5e-6]
Here two simulations will be generated, one using tau=0.51
and F.x=1e-5
and the other one with tau=0.505
and F.x=5e-6
.
They will both have the same name, but the first one will have ID 0 and the other ID 1.
Note
Every simulation has an ID. If it doesn’t use any unroll, it will be 0. If it unrolls any fields, the ID will be the index in the unroll list.
Note that the two !unroll
tags have the same length, this is required.
If any list has a different size than the other ones, the configuration will raise an error.
Note
For parent simulations, everything is inherited, including the tags such as !unroll
.
If you don’t wish to use any key, you must overwrite it.
Variables substitution (!sub
)#
There is a field in the simulation, variables
, that is used to define the simulation variables and other values that may be used for other fields.
These ones can be referenced in other places as ${key_name}
when using the !sub
tag (it also works for the !math
tag).
variables:
base_path: /home/ubuntu/my_user
u_ref: 0.05
height_ref: 8
time_scale:
reference_cst: !math ${height_ref}/${u_ref}
n_csts_run: 300
time_steps_develop: 5000
domain:
sizes: [32, 48, 64]
simulations:
- name: mySimulation
save_path: !sub ${base_path}/simulation0/results/
time_steps: !math ${time_scale.time_steps_develop} + ${time_scale.n_csts_run}*${time_scale.reference_cst}
domain:
domain_size:
x: !math ${domain.sizes[0]}
y: !math ${domain.sizes[2]}
z: !math ${domain.sizes[1]}
Special Variables#
There are some internal special variables that you can use for substitution:
variables:
version: !sub "${NASSU_VERSION}" # x.y.z
filepath: !sub "${NASSU_FILE_PATH}" # docs/source/user_guide/02_config/file/kitchensink.nassu.yaml
foldername: !sub "${NASSU_FILE_FOLDER}" # docs/source/user_guide/02_config/file
save_folder: !sub "${NASSU_FILE_FOLDER}/results/${NASSU_VERSION}/"
Anchors and aliases#
Suppose that we have a value or series of fields that are used in multiple parts of the file. It would be good if it was possible for us to create in one place and let the other fields reference it. Using YAML anchors and aliases allows us to do just that. They serve as a reference that can be pointed to by anywhere in the file
variables:
base_path: &ANCHOR_BASE_PATH my/path/to/use
interval_export: &ANCHOR_INTERVAL_EXPORT 5000
report_cfg: &ANCHOR_REPORT_CFG:
start_step: 1000
end_step: !math 1000*20
frequency: 100
simulation:
- name: mySimulation
output: !concat [*ANCHOR_BASE_PATH, "output/"]
report: *ANCHOR_REPORT_CFG
domain:
bodies:
building:
lnas_path: !sub "${base_path}/lnas/building.yaml"
data:
instantaneous:
default: { interval: { frequency: *ANCHOR_INTERVAL_EXPORT }, macrs: [rho, u] }
Using this feature it is easier to reference a common information in the file and do tricks as the example presents.
It’s important to notice that we create a special key for these anchors, variables
, to keep all the anchors centralized.
The other tags also work in the anchors, so you can use !math
, !concat
or !range
and it will work as expected.
Configuration from other file (dependencies
)#
It’s also possible to distribute the configurations among different files. Suppose you have a file that defines a base configuration for multiple purposes or cases. One way to reference these configurations would be to simply copy and paste this configuration into the other cases. But if anything changes in the default configuration, all files must be manually updated.
To facilitate this job of referencing a common configuration, it’s possible to load the configurations from other files before starting our own.
# ./base_simul.yaml
simulations:
- name: baseSimulation
models:
LBM:
vel_set: D2Q9
coll_oper: RRBGK
tau: 0.501
F:
x: 1e-6
# ./my_simul.yaml
dependencies:
sim_cfg_files: [./base_simul.yaml]
simulation:
- name: actualSimulation
parent: baseSimulation
domain:
bodies:
building: ...
The dependencies.sim_cfg_files
consists of a list of configuration files with simulations to load.
These loaded simulations can be used as parent of our own.
Important to mention that the simulations from other files are not added to the list of simulations of the current file.
Important
The path used must be relative to the current path of your shell, not to the file itself.
The loading algorithm is able to check for cyclic dependencies and the order in which the simulations must be stated.
Full structure example#
A full example, using all presented capabilities, is presented below
dependencies:
sim_cfg_files: [parent_cfg.yaml]
variables:
base_path: &MY_BASE_PATH: "building_case"
interval_export: &INTERVAL_EXPORT: 5000
report_cfg: &REPORT_CFG:
start_step: 1000
end_step: !math ${report_cfg.start_step}*20
frequency: 100
simulation:
- name: BuildingSimulation
parent: baseSimulation # Defined in parent_cfg.yaml
output: !sub ${base_path}/output/"
report: *REPORT_CFG
domain:
bodies:
building:
lnas_path: !concat [*MY_BASE_PATH, "/lnas/building.yaml"]
refinement: !not-inherit
static:
default:
bodies:
- body_name: building
lvl: 5
normal_offsets: !range [-0.25, 2.1, 0.25]
data:
instantaneous:
default: { interval: { frequency: *INTERVAL_EXPORT }, macrs: [rho, u] }
models:
LBM:
vel_set: !unroll [D3Q27, D3Q19]
coll_oper: !unroll [RRBGK, HRRBGK]