# 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. ```yaml 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 ```yaml 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 } # Height to assume for surface, for volumetric algorithms. # Defaults to 1 height_assume: 1 # Wheter the surface height scales per level or not. The scaling is: # height_lvl = height_assume * 2^lvl # Defaults to false height_scales_per_lvl: false # Treatment triangles for small triangles # add: adds the small triangles # ignore: ignore the small triangles # Defaults to error small_triangles: "add" # | "ignore" # Add copy of this geometry in given normal offsets. # Defaults to [] (empty list) normal_offsets_add: !range [-5, 1, 1] # 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 ```yaml 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: 1. Translate body to centralize at (0, 0, 0) the fixed point 2. Apply scale transformation 3. Apply rotation transformation 4. Apply translation transformation 5. Revert the translation done in step 1 For more informations and specifications on how this is done, check the [LNAS](https://github.com/AeroSim-CFD/lnas) repository. ## Domain Refinement For the domain refinement specification, the `domain.refinement` field is used ```yaml 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. ```yaml 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](./data.md). ``` 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.