LCOV - code coverage report
Current view: top level - boundary/cpu - boundary_conditions_outlet_scalar.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 66.7 % 24 16
Test Date: 2026-03-04 10:22:18 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /**
       2              :  * Outlet Boundary Conditions - Scalar (CPU) Implementation
       3              :  *
       4              :  * Baseline scalar implementation of outlet boundary conditions.
       5              :  * No SIMD, no OpenMP - pure C loops.
       6              :  *
       7              :  * Supports:
       8              :  * - Zero-gradient (Neumann) outlet
       9              :  * - Convective outlet (advection-based)
      10              :  * - 3D z-face outlets (FRONT/BACK edges)
      11              :  */
      12              : 
      13              : #include "../boundary_conditions_outlet_common.h"
      14              : 
      15           48 : cfd_status_t bc_apply_outlet_scalar_impl(double* field, size_t nx, size_t ny,
      16              :                                           size_t nz, size_t stride_z,
      17              :                                           const bc_outlet_config_t* config) {
      18           48 :     if (!field || !config || nx < 3 || ny < 3) {
      19              :         return CFD_ERROR_INVALID;
      20              :     }
      21              : 
      22           93 :     if (!bc_outlet_is_valid_edge(config->edge)) {
      23              :         return CFD_ERROR_INVALID;
      24              :     }
      25              : 
      26           45 :     if (!bc_outlet_is_valid_type(config->type)) {
      27              :         return CFD_ERROR_INVALID;
      28              :     }
      29              : 
      30           44 :     int edge_idx = bc_outlet_edge_to_index(config->edge);
      31           44 :     const bc_outlet_edge_loop_t* loop = &bc_outlet_edge_loops[edge_idx];
      32              : 
      33           44 :     switch (config->type) {
      34              :         case BC_OUTLET_ZERO_GRADIENT:
      35              :         case BC_OUTLET_CONVECTIVE:
      36              :             /* Both types use zero-gradient for now.
      37              :              * Full convective BC would require temporal information. */
      38           44 :             if (loop->is_z_face) {
      39              :                 /* Z-face outlet (FRONT or BACK): copy entire xy-plane from adjacent interior */
      40            1 :                 if (nz <= 1) {
      41              :                     return CFD_ERROR_INVALID;
      42              :                 }
      43            0 :                 size_t dst_plane, src_plane;
      44            0 :                 if (config->edge == BC_EDGE_FRONT) {
      45            0 :                     dst_plane = (nz - 1) * stride_z;
      46            0 :                     src_plane = ((nz - 2) * stride_z);
      47              :                 } else { /* BC_EDGE_BACK */
      48              :                     dst_plane = 0;
      49              :                     src_plane = stride_z;
      50              :                 }
      51            0 :                 for (size_t j = 0; j < ny; j++) {
      52            0 :                     for (size_t i = 0; i < nx; i++) {
      53            0 :                         size_t offset = IDX_2D(i, j, nx);
      54            0 :                         field[dst_plane + offset] = field[src_plane + offset];
      55              :                     }
      56              :                 }
      57              :             } else {
      58              :                 /* X/Y-face outlet: loop over each z-plane */
      59           43 :                 size_t count = loop->use_ny_for_count ? ny : nx;
      60           86 :                 for (size_t k = 0; k < nz; k++) {
      61           43 :                     size_t base = k * stride_z;
      62          439 :                     for (size_t i = 0; i < count; i++) {
      63          396 :                         size_t dst_idx = base + loop->dst_fn(i, nx, ny);
      64          396 :                         size_t src_idx = base + loop->src_fn(i, nx, ny);
      65          396 :                         field[dst_idx] = field[src_idx];
      66              :                     }
      67              :                 }
      68              :             }
      69              :             break;
      70              : 
      71              :         default:
      72              :             return CFD_ERROR_INVALID;
      73              :     }
      74              : 
      75              :     return CFD_SUCCESS;
      76              : }
        

Generated by: LCOV version 2.0-1