Domain#
When configuring a simulation, one of the first things required is to define the domain. What is considered here by domain is:
Domain size for the simulation
Bodies in this volume
Refinements to apply in the volume
Domain size#
The domain size for the simulation is the volume in which the simulation will run.
simulations:
- name: example
domain:
# All dimensions in domain_size MUST BE divisible by block_size
domain_size:
x: 96
y: 80
z: 128
# Rescale domain for output
# pos_rescaled = pos * scale + translation
domain_rescale:
translation: [0, 0, 0]
scale: [1, 1, 1]
# Leave it as 8
block_size: 8
Note
Currently the simulation volume supports only a box (2D or 3D)
The domain is divided in blocks that are boxes with size block_size
.
These blocks can be refined recursively, which generate nodes that have half the distance between them.
The higher the level, the more refined it is, with level 0 being the domain with no refinement.
Blocks communicate with each other through neighbours on the same level, or with their parent/children of different level.
Important
All dimensions in the domain_size
must be divisible by block_size
.
For the block size, there is a limitation between it and the shared memory size of the GPU. It’s recommended to leave it as 8, because most GPUs will be able to run the simulation with this size.
It’s possible to rescale the domain. This is useful for changing system coordinates, from LBM to meters, for example.
This can be done through the domain_rescale
field.
Bodies#
For the bodies inside the domain the field domain.bodies
is used
simulations:
- name: example
domain:
bodies:
# Body named CAARC
CAARC:
# IBM configurations
IBM:
# True to run this body
# Defaults to true
run: True
# IBM configuration name, at `models.IBM.cfgs.{cfg_name}`
# Defaults to "default"
cfg_use: cfg_name
# IBM order for forces interpolation spread
# Bodies in same order have forces calculated at the same time (don't affect each other)
# Forces are computed from smaller to bigger order, similar to how BC is done
# Defaults to 0
order: 0
# Interval in time steps in which to run IBM
# When end step or start step is zero, they're not applied
# Defaults to {end_step: 0, start_step: 0} (full simulation)
interval_run:
end_step: 0
start_step: 0
# Path to .lnas file for geometry
lnas_path: fixture/lnas/wind_tunnel/CAARC.lnas
# The min max area for the triangles to use (considering lvl 0)
# bigger triangles are refined until reach the level area
# smaller triangles are treated as `small_triangles`
# `max` should be at least 4 times`the `min` size
# Defaults to { min: 0.25, max: 1 }
area: { min: 0.25, max: 1 }
# Treatment triangles for small triangles
# error: raises an error if they exists
# add: adds the small triangles
# ignore: ignore the small triangles
# Defaults to error
small_triangles: "error" # | "add" | "remove"
# Volumes limit, remove triangles outside it in each geometry step
# Defaults to no limit (no triangle is removed)
volumes_limits:
# These volumes are before any transformation in the body
raw:
- start: [10, 20, 0]
end: [100, 100, 100]
# These are applied after the body's transformations
body_transformed:
- start: [60, 40, 0]
end: [100, 200, 100]
# These are applied after all transformations are applied
full_transformed:
- start: [60, 40, 0]
end: [100, 200, 100]
- start: [100, 40, 50]
end: [150, 140, 70]
# Transformations to apply in the body
# For more information check the `transformations` section
# Defaults to no transformation
transformation:
fixed_point: [0, 0, 0]
# Rotation is in radians
rotation: [0, 0, 0]
scale: [1.0, 1.0, 1.0]
translation: [12.0, 0.0, 1.0]
# Another body, the only required field is lnas_path, all others are optional
cube:
lnas_path: fixture/lnas/basic/cube.lnas
# Domain limits for effect of bodies in the domain
# (i.e. There are no IBM nodes outside this volume)
bodies_domain_limits:
start: [8.0, 4.0, 0.0]
end: [448.0, 156.0, 48.0]
# Defaults to true
is_abs: true
Important
The body uses a .lnas
file for the geometry specification.
The geometry consists of a series of triangles and vertices, which are used and processed in multiple ways.
The file also have a list of surfaces that are defined by a series of triangles in the geometry. This surfaces may be used for multiple purposes as well.
Point Cloud#
For specification of point clouds the field domain.point_cloud
is used
simulations:
- name: example
domain:
point_cloud:
# Point cloud named TreeCloud
TreeCloud:
# IBM configurations, same from bodies, to specify IBM to run
IBM:
run: True
cfg_use: cfg_name
order: 0
interval_run:
end_step: 0
start_step: 0
# Path to .csv file for point cloud
# Must have keys: [x, y, z, nx, ny, nz, area]
csv_path: fixture/point_cloud/tree.csv
# Transformation to apply in the point cloud
# For more information check the `transformations` section
# Defaults to no transformation
transformation:
fixed_point: [0, 0, 0]
# Rotation is in radians
rotation: [0, 0, 0]
scale: [1.0, 1.0, 1.0]
translation: [12.0, 0.0, 1.0]
# Another body, the only required field is lnas_path, all others are optional
another_point_cloud:
csv_path: fixture/point_cloud/cube.csv
Transformations#
It’s possible to apply transformations to the bodies. The operations that we support are:
Scaling
Rotation
Translation
These are all linear transformations that are applied sequentially. There is also an important aspect which is the fixed point, that defined the point in which the geometry is scaled and rotated in relation to.
The full order of transformations is:
Translate body to centralize at (0, 0, 0) the fixed point
Apply scale transformation
Apply rotation transformation
Apply translation transformation
Revert the translation done in step 1
For more informations and specifications on how this is done, check the LNAS repository.
Domain Refinement#
For the domain refinement specification, the domain.refinement
field is used
simulations:
- name: example
domain:
refinement:
static:
# Refining a volume
volume_refine:
# List of volumes to refine
volumes_refine:
# The volume specification and level to refine.
# It's possible to use a relative volume by specifying is_abs: False
# By default is_abs defauls to true
# All blocks inside these volumes are refined
- lvl: 1
start: [0.0, 0.0, 0.0]
end: [32.0, 160.0, 64.0]
# Defaults to true
is_abs: true
# Refining a body
body_refine:
bodies:
# Bodies to refine
- body_name: CAARC
# Level to use
lvl: 4
# Normals offset to refine
# This offsets the vertices in normal direction multiplying by the offset
# and refines this body. All blocks that the body is in are refined
normal_offsets: !range [-0.5, 2.1, 0.5]
# It's possible to specify only a surface of the body for usage too
- body_name: CAARC.surface_name
lvl: 4
normal_offsets: !math [1/4]
# Transformation to apply to body for transformation
transformation:
translation: [0.0, 0.0, -1.0]
fixed_point: [0, 0, 0]
rotation: [0, 0, 0]
scale: [1.0, 1.0, 1.0]
# Limiting the volume for refinement
limit_volume:
bodies:
- body_name: CAARC
lvl: 6
normal_offsets: [0, 1]
# This limits the volume that can be refined by all refinemets (volume and body)
volume_refinement_limit:
start: [0, 10, 0]
end: [40, 50, 150]
# Defaults to true
is_abs: true
# Ignoring volumes
ignore_volumes:
bodies:
- body_name: CAARC
lvl: 6
normal_offsets: !range [-0.5, 5, 0.2]
# List of volumes to not refine.
# If a block is fully inside any of these volumes it's not refined
volumes_not_refine:
- start: [0, 10, 0]
end: [40, 50, 150]
# Defaults to true
is_abs: true
- start: [0, 0.15, 0.1]
end: [0.1, 0.2, 0.3]
# Example using all cases presented above
full_example:
volumes_refine:
- is_abs: true
lvl: 1
start: [0.0, 0.0, 0.0]
end: [32.0, 160.0, 64.0]
- is_abs: true
lvl: 4
start: [10, 20, 30]
end: [32.0, 160.0, 64.0]
bodies:
- body_name: CAARC
lvl: 6
normal_offsets: [-0.1, 0, 0.1]
volume_refinement_limit:
is_abs: true
start: [0, 10, 0]
end: [40, 50, 150]
volumes_not_refine:
- is_abs: true
start: [0, 10, 0]
end: [40, 50, 150]
- is_abs: false
start: [0, 0.15, 0.1]
end: [0.1, 0.2, 0.3]
Important
The refinement follows some rules, one important is that blocks that “communicate” with each other are at most one level difference. So when specifying a volume to refine up to level 2, the blocks in the limit of this volume will be at level 1.
Global transformations#
When considering a change of scale, rotation of domain or change of perspective, it’s common to apply these in multiple geometries and entities in the domain.
For this we provide the field global_transformations
, that allows the user to apply the same transformation to multiple entities.
global_transformations:
# List of transformations to apply
- transformation:
translation: [0, 10, 3.6]
point_clouds_apply: ["tree", "one_sponge"]
bodies_apply: ["CAARC"]
probes_apply:
[
"series.series1.lines",
"series.series1.points.point1",
"series.another_series",
"spectrum.downstream",
]
# True to apply this transformation to bodies in series as well
apply_to_bodies_probes: false
# Another transformation
- transformation:
fixed_point: [608.90625, 64, 0]
rotation: [0, 0, 3.141592654]
scale: [1, 1, 1]
point_clouds_aply: []
bodies_apply: ["CAARC"]
probes_apply: []
It’s possible to define a list of transformations to apply for a list of bodies and probes. These are applied after the body specific ones and in sequence to each other. So in the example above, first the translation is applied to the body and the probes and only after that the body is rotated. The same rules serves for the probes.
Note
To know more about probes, check their section in data.
For the probes, it’s possible to select a series of probes in it.
Say the transformation must be applied to all lines in the series called series1
.
We can specify it using the series.series1.lines
.
But if we want to apply it only to a single line called my_line
, we’re able to do it using series.series1.lines.my_line
.
Same applies to transform all geometries in a series or other fields such as bodies
, points
or csvs
.
To transform spectrum points the rule is the same, using spectrum.point_name
to transform a point with the given name, or simply spectrum
to apply to all spectrum points.