LCOV - code coverage report
Current view: top level - boundary - boundary_conditions_outlet_common.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 28 28
Test Date: 2026-03-04 10:22:18 Functions: 100.0 % 8 8

            Line data    Source code
       1              : /**
       2              :  * Outlet Boundary Conditions - Common Definitions
       3              :  *
       4              :  * Shared helper functions and data structures used by all outlet BC
       5              :  * backend implementations (scalar, OMP, AVX2, NEON).
       6              :  *
       7              :  * This header is internal and should only be included by outlet BC
       8              :  * implementation files.
       9              :  */
      10              : 
      11              : #ifndef CFD_BOUNDARY_CONDITIONS_OUTLET_COMMON_H
      12              : #define CFD_BOUNDARY_CONDITIONS_OUTLET_COMMON_H
      13              : 
      14              : #include "boundary_conditions_internal.h"
      15              : #include "cfd/core/indexing.h"
      16              : 
      17              : /* ============================================================================
      18              :  * Edge validation
      19              :  *
      20              :  * bc_edge_t uses bit flags (0x01..0x20) for potential combining.
      21              :  * We convert these to sequential indices (0-5) for array lookup.
      22              :  * ============================================================================ */
      23              : 
      24              : /**
      25              :  * Check if edge value is valid (exactly one of the six valid edges).
      26              :  */
      27           61 : static inline bool bc_outlet_is_valid_edge(bc_edge_t edge) {
      28           61 :     return edge == BC_EDGE_LEFT || edge == BC_EDGE_RIGHT ||
      29              :            edge == BC_EDGE_BOTTOM || edge == BC_EDGE_TOP ||
      30              :            edge == BC_EDGE_FRONT || edge == BC_EDGE_BACK;
      31              : }
      32              : 
      33              : /**
      34              :  * Check if outlet type is valid.
      35              :  */
      36              : static inline bool bc_outlet_is_valid_type(bc_outlet_type_t type) {
      37              :     return type == BC_OUTLET_ZERO_GRADIENT || type == BC_OUTLET_CONVECTIVE;
      38              : }
      39              : 
      40              : /* ============================================================================
      41              :  * Index computation functions for each edge
      42              :  *
      43              :  * For zero-gradient outlet: boundary = adjacent interior value
      44              :  * Left:   field[j*nx + 0] = field[j*nx + 1]
      45              :  * Right:  field[j*nx + nx-1] = field[j*nx + nx-2]
      46              :  * Bottom: field[i] = field[nx + i]
      47              :  * Top:    field[(ny-1)*nx + i] = field[(ny-2)*nx + i]
      48              :  * Back:   field[k=0 plane] = field[k=1 plane]      (3D only)
      49              :  * Front:  field[k=nz-1 plane] = field[k=nz-2 plane] (3D only)
      50              :  * ============================================================================ */
      51              : 
      52              : typedef size_t (*bc_outlet_idx_func_t)(size_t i, size_t nx, size_t ny);
      53              : 
      54              : /* Destination index functions (boundary) */
      55          107 : static inline size_t bc_outlet_dst_left(size_t j, size_t nx, size_t ny) {
      56          107 :     (void)ny;
      57          107 :     return IDX_2D(0, j, nx);
      58              : }
      59              : 
      60          347 : static inline size_t bc_outlet_dst_right(size_t j, size_t nx, size_t ny) {
      61          347 :     (void)ny;
      62          347 :     return IDX_2D(nx - 1, j, nx);
      63              : }
      64              : 
      65          107 : static inline size_t bc_outlet_dst_bottom(size_t i, size_t nx, size_t ny) {
      66          107 :     (void)nx; (void)ny;
      67          107 :     return i;
      68              : }
      69              : 
      70          107 : static inline size_t bc_outlet_dst_top(size_t i, size_t nx, size_t ny) {
      71          107 :     return IDX_2D(i, ny - 1, nx);
      72              : }
      73              : 
      74              : /* Source index functions (adjacent interior) */
      75          107 : static inline size_t bc_outlet_src_left(size_t j, size_t nx, size_t ny) {
      76          107 :     (void)ny;
      77          107 :     return IDX_2D(1, j, nx);
      78              : }
      79              : 
      80          347 : static inline size_t bc_outlet_src_right(size_t j, size_t nx, size_t ny) {
      81          347 :     (void)ny;
      82          347 :     return IDX_2D(nx - 2, j, nx);
      83              : }
      84              : 
      85          107 : static inline size_t bc_outlet_src_bottom(size_t i, size_t nx, size_t ny) {
      86          107 :     (void)ny;
      87          107 :     return nx + i;
      88              : }
      89              : 
      90          107 : static inline size_t bc_outlet_src_top(size_t i, size_t nx, size_t ny) {
      91          107 :     return IDX_2D(i, ny - 2, nx);
      92              : }
      93              : 
      94              : /**
      95              :  * Edge loop configuration for table-driven boundary application.
      96              :  */
      97              : typedef struct {
      98              :     bc_outlet_idx_func_t dst_fn;        /* Boundary index computation (NULL for z-faces) */
      99              :     bc_outlet_idx_func_t src_fn;        /* Interior index computation (NULL for z-faces) */
     100              :     int use_ny_for_count;               /* 1 if loop count is ny, 0 if nx (ignored for z-faces) */
     101              :     int is_z_face;                      /* 1 for front/back z-face edges */
     102              : } bc_outlet_edge_loop_t;
     103              : 
     104              : /**
     105              :  * Edge loop configuration indexed 0-5 (left, right, bottom, top, front, back).
     106              :  */
     107              : static const bc_outlet_edge_loop_t bc_outlet_edge_loops[6] = {
     108              :     { .dst_fn = bc_outlet_dst_left,   .src_fn = bc_outlet_src_left,   .use_ny_for_count = 1, .is_z_face = 0 },
     109              :     { .dst_fn = bc_outlet_dst_right,  .src_fn = bc_outlet_src_right,  .use_ny_for_count = 1, .is_z_face = 0 },
     110              :     { .dst_fn = bc_outlet_dst_bottom, .src_fn = bc_outlet_src_bottom, .use_ny_for_count = 0, .is_z_face = 0 },
     111              :     { .dst_fn = bc_outlet_dst_top,    .src_fn = bc_outlet_src_top,    .use_ny_for_count = 0, .is_z_face = 0 },
     112              :     { .dst_fn = NULL,                 .src_fn = NULL,                 .use_ny_for_count = 0, .is_z_face = 1 },  /* FRONT */
     113              :     { .dst_fn = NULL,                 .src_fn = NULL,                 .use_ny_for_count = 0, .is_z_face = 1 },  /* BACK */
     114              : };
     115              : 
     116              : /**
     117              :  * Convert bc_edge_t bit flag to sequential array index (0-5).
     118              :  * BC_EDGE_LEFT (0x01) -> 0, BC_EDGE_RIGHT (0x02) -> 1,
     119              :  * BC_EDGE_BOTTOM (0x04) -> 2, BC_EDGE_TOP (0x08) -> 3,
     120              :  * BC_EDGE_FRONT (0x10) -> 4, BC_EDGE_BACK (0x20) -> 5
     121              :  *
     122              :  * Uses bit manipulation to find the position of the least significant set bit
     123              :  * by counting trailing zeros in the bit flag (clamped to the range 0-5).
     124              :  * The behavior is only defined for valid, single-bit edges; callers must
     125              :  * ensure validity via bc_outlet_is_valid_edge() before calling.
     126              :  */
     127              : static inline int bc_outlet_edge_to_index(bc_edge_t edge) {
     128              :     int idx = 0;
     129              :     unsigned int e = (unsigned int)edge;
     130          143 :     while ((e & 1) == 0 && idx < 5) {
     131           87 :         e >>= 1;
     132           87 :         idx++;
     133              :     }
     134           56 :     return idx;
     135              : }
     136              : 
     137              : #endif /* CFD_BOUNDARY_CONDITIONS_OUTLET_COMMON_H */
        

Generated by: LCOV version 2.0-1