LCOV - code coverage report
Current view: top level - solvers/navier_stokes - boundary_copy_utils.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 100.0 % 36 36
Test Date: 2026-03-04 10:22:18 Functions: 100.0 % 1 1

            Line data    Source code
       1              : /**
       2              :  * @file boundary_copy_utils.h
       3              :  * @brief Shared boundary copying utilities for projection method solvers
       4              :  *
       5              :  * This header provides helper functions used across all projection solver
       6              :  * backends (CPU, AVX2, OpenMP) to copy boundary velocity values.
       7              :  *
       8              :  * Include from backend subdirectories as: #include "../boundary_copy_utils.h"
       9              :  */
      10              : 
      11              : #ifndef BOUNDARY_COPY_UTILS_H
      12              : #define BOUNDARY_COPY_UTILS_H
      13              : 
      14              : #include "cfd/core/indexing.h"
      15              : #include <stddef.h>
      16              : 
      17              : /**
      18              :  * Copy boundary values between velocity arrays
      19              :  *
      20              :  * Used to preserve caller-set boundary conditions (e.g., lid velocity for
      21              :  * cavity flow) during the projection method's predictor and corrector steps.
      22              :  *
      23              :  * Copies ALL four boundaries (top, bottom, left, right). For flows with
      24              :  * outlet boundaries (Neumann BCs), use copy_dirichlet_boundaries instead.
      25              :  *
      26              :  * @param dst_u  Destination u-velocity array
      27              :  * @param dst_v  Destination v-velocity array
      28              :  * @param src_u  Source u-velocity array
      29              :  * @param src_v  Source v-velocity array
      30              :  * @param nx     Grid width
      31              :  * @param ny     Grid height
      32              :  */
      33              : static inline void copy_boundary_velocities(double* dst_u, double* dst_v,
      34              :                                             const double* src_u, const double* src_v,
      35              :                                             size_t nx, size_t ny) {
      36              :     // Bottom and top boundaries (j = 0 and j = ny-1)
      37              :     for (size_t i = 0; i < nx; i++) {
      38              :         dst_u[i] = src_u[i];
      39              :         dst_v[i] = src_v[i];
      40              :         dst_u[IDX_2D(i, ny - 1, nx)] = src_u[IDX_2D(i, ny - 1, nx)];
      41              :         dst_v[IDX_2D(i, ny - 1, nx)] = src_v[IDX_2D(i, ny - 1, nx)];
      42              :     }
      43              :     // Left and right boundaries (i = 0 and i = nx-1)
      44              :     for (size_t j = 1; j < ny - 1; j++) {
      45              :         dst_u[IDX_2D(0, j, nx)] = src_u[IDX_2D(0, j, nx)];
      46              :         dst_v[IDX_2D(0, j, nx)] = src_v[IDX_2D(0, j, nx)];
      47              :         dst_u[IDX_2D(nx - 1, j, nx)] = src_u[IDX_2D(nx - 1, j, nx)];
      48              :         dst_v[IDX_2D(nx - 1, j, nx)] = src_v[IDX_2D(nx - 1, j, nx)];
      49              :     }
      50              : }
      51              : 
      52              : /**
      53              :  * Copy only Dirichlet boundary values (walls + inlet), skip outlet
      54              :  *
      55              :  * Used for flows with outlet boundaries (e.g., Poiseuille channel flow).
      56              :  * Copies top, bottom, and left boundaries, but NOT the right boundary
      57              :  * to allow the pressure correction to update the outlet velocity.
      58              :  *
      59              :  * @param dst_u  Destination u-velocity array
      60              :  * @param dst_v  Destination v-velocity array
      61              :  * @param src_u  Source u-velocity array
      62              :  * @param src_v  Source v-velocity array
      63              :  * @param nx     Grid width
      64              :  * @param ny     Grid height
      65              :  */
      66              : static inline void copy_dirichlet_boundaries(double* dst_u, double* dst_v,
      67              :                                              const double* src_u, const double* src_v,
      68              :                                              size_t nx, size_t ny) {
      69              :     // Bottom and top boundaries (j = 0 and j = ny-1)
      70              :     for (size_t i = 0; i < nx; i++) {
      71              :         dst_u[i] = src_u[i];
      72              :         dst_v[i] = src_v[i];
      73              :         dst_u[IDX_2D(i, ny - 1, nx)] = src_u[IDX_2D(i, ny - 1, nx)];
      74              :         dst_v[IDX_2D(i, ny - 1, nx)] = src_v[IDX_2D(i, ny - 1, nx)];
      75              :     }
      76              :     // Left boundary only (i = 0) - skip right boundary to preserve outlet
      77              :     for (size_t j = 1; j < ny - 1; j++) {
      78              :         dst_u[IDX_2D(0, j, nx)] = src_u[IDX_2D(0, j, nx)];
      79              :         dst_v[IDX_2D(0, j, nx)] = src_v[IDX_2D(0, j, nx)];
      80              :     }
      81              : }
      82              : 
      83              : /**
      84              :  * Copy boundary values for 3D velocity arrays (u, v, w on all 6 faces)
      85              :  *
      86              :  * When nz <= 1, copies only the 4 xy-boundary edges (same as 2D) and
      87              :  * ignores w. When nz > 1, also copies the front/back z-faces.
      88              :  *
      89              :  * @param dst_u, dst_v, dst_w  Destination velocity arrays
      90              :  * @param src_u, src_v, src_w  Source velocity arrays
      91              :  * @param nx, ny, nz           Grid dimensions (nz=1 for 2D)
      92              :  */
      93        23296 : static inline void copy_boundary_velocities_3d(
      94              :     double* dst_u, double* dst_v, double* dst_w,
      95              :     const double* src_u, const double* src_v, const double* src_w,
      96              :     size_t nx, size_t ny, size_t nz)
      97              : {
      98        23296 :     size_t plane = nx * ny;
      99              : 
     100        63118 :     for (size_t k = 0; k < nz; k++) {
     101        39822 :         size_t base = k * plane;
     102              : 
     103              :         /* Bottom and top y-boundaries (j = 0 and j = ny-1) */
     104      1467836 :         for (size_t i = 0; i < nx; i++) {
     105      1428014 :             size_t bot = base + i;
     106      1428014 :             size_t top = base + IDX_2D(i, ny - 1, nx);
     107      1428014 :             dst_u[bot] = src_u[bot];
     108      1428014 :             dst_v[bot] = src_v[bot];
     109      1428014 :             dst_u[top] = src_u[top];
     110      1428014 :             dst_v[top] = src_v[top];
     111      1428014 :             if (nz > 1) {
     112       269952 :                 dst_w[bot] = src_w[bot];
     113       269952 :                 dst_w[top] = src_w[top];
     114              :             }
     115              :         }
     116              :         /* Left and right x-boundaries (i = 0 and i = nx-1) */
     117      1385004 :         for (size_t j = 1; j < ny - 1; j++) {
     118      1345182 :             size_t left = base + IDX_2D(0, j, nx);
     119      1345182 :             size_t right = base + IDX_2D(nx - 1, j, nx);
     120      1345182 :             dst_u[left] = src_u[left];
     121      1345182 :             dst_v[left] = src_v[left];
     122      1345182 :             dst_u[right] = src_u[right];
     123      1345182 :             dst_v[right] = src_v[right];
     124      1345182 :             if (nz > 1) {
     125       234464 :                 dst_w[left] = src_w[left];
     126       234464 :                 dst_w[right] = src_w[right];
     127              :             }
     128              :         }
     129              :     }
     130              : 
     131              :     /* Front and back z-faces (k = 0 and k = nz-1) */
     132        23296 :     if (nz > 1) {
     133         1218 :         size_t back_base = (nz - 1) * plane;
     134        16526 :         for (size_t j = 1; j < ny - 1; j++) {
     135       219156 :             for (size_t i = 1; i < nx - 1; i++) {
     136       203848 :                 size_t off = IDX_2D(i, j, nx);
     137              :                 /* k = 0 face */
     138       203848 :                 dst_u[off] = src_u[off];
     139       203848 :                 dst_v[off] = src_v[off];
     140       203848 :                 dst_w[off] = src_w[off];
     141              :                 /* k = nz-1 face */
     142       203848 :                 dst_u[back_base + off] = src_u[back_base + off];
     143       203848 :                 dst_v[back_base + off] = src_v[back_base + off];
     144       203848 :                 dst_w[back_base + off] = src_w[back_base + off];
     145              :             }
     146              :         }
     147              :     }
     148        23296 : }
     149              : 
     150              : #endif /* BOUNDARY_COPY_UTILS_H */
        

Generated by: LCOV version 2.0-1