LCOV - code coverage report
Current view: top level - boundary/cpu - boundary_conditions_inlet_time_scalar.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.5 % 52 33
Test Date: 2026-03-04 10:22:18 Functions: 100.0 % 2 2

            Line data    Source code
       1              : /**
       2              :  * Time-Varying Inlet Boundary Conditions - Scalar (CPU) Implementation
       3              :  *
       4              :  * Baseline scalar implementation of time-varying inlet velocity boundary
       5              :  * conditions. Extends the standard inlet BC with time modulation support.
       6              :  *
       7              :  * Supports:
       8              :  * - All standard inlet profiles (uniform, parabolic, custom)
       9              :  * - Time modulation: sinusoidal, ramp, step
      10              :  * - Custom time-varying profile callback
      11              :  * - 3D z-face inlets (FRONT/BACK edges)
      12              :  */
      13              : 
      14              : #include "../boundary_conditions_inlet_common.h"
      15              : #include "../boundary_conditions_time.h"
      16              : 
      17              : /**
      18              :  * Compute inlet velocity with time modulation at given position.
      19              :  *
      20              :  * This combines the spatial profile (uniform, parabolic, custom) with
      21              :  * time modulation (sinusoidal, ramp, step, custom).
      22              :  *
      23              :  * @param config    Inlet configuration with time settings
      24              :  * @param position  Normalized position along the edge [0, 1]
      25              :  * @param time      Current simulation time
      26              :  * @param dt        Current time step
      27              :  * @param u_out     Output: u velocity component
      28              :  * @param v_out     Output: v velocity component
      29              :  */
      30          240 : static void bc_inlet_compute_velocity_time(const bc_inlet_config_t* config,
      31              :                                             double position,
      32              :                                             double time, double dt,
      33              :                                             double* u_out, double* v_out) {
      34              :     /* Check for custom time-varying profile callback first */
      35          240 :     if (config->custom_profile_time != NULL) {
      36           16 :         config->custom_profile_time(position, time, dt, u_out, v_out,
      37           16 :                                     config->custom_profile_time_user_data);
      38           16 :         return;
      39              :     }
      40              : 
      41              :     /* Compute base velocity from spatial profile */
      42          224 :     double u_base, v_base;
      43          224 :     bc_inlet_compute_velocity(config, position, &u_base, &v_base);
      44              : 
      45              :     /* Apply time modulation */
      46          224 :     double modulator = bc_time_get_modulator(&config->time_config, time, dt);
      47          224 :     *u_out = u_base * modulator;
      48          224 :     *v_out = v_base * modulator;
      49              : }
      50              : 
      51           19 : cfd_status_t bc_apply_inlet_time_scalar_impl(double* u, double* v, double* w,
      52              :                                               size_t nx, size_t ny,
      53              :                                               size_t nz, size_t stride_z,
      54              :                                               const bc_inlet_config_t* config,
      55              :                                               const bc_time_context_t* time_ctx) {
      56           19 :     if (!u || !v || !config || nx < 3 || ny < 3) {
      57              :         return CFD_ERROR_INVALID;
      58              :     }
      59           16 :     if (nz == 0 || nz == 2 || (nz > 1 && stride_z < nx * ny)) {
      60              :         return CFD_ERROR_INVALID;
      61              :     }
      62              : 
      63           16 :     if (!time_ctx) {
      64              :         /* If no time context provided, use time=0, dt=0 */
      65            1 :         bc_time_context_t default_ctx = {0.0, 0.0};
      66            1 :         return bc_apply_inlet_time_scalar_impl(u, v, w, nx, ny, nz, stride_z,
      67              :                                                 config, &default_ctx);
      68              :     }
      69              : 
      70           30 :     if (!bc_inlet_is_valid_edge(config->edge)) {
      71              :         return CFD_ERROR_INVALID;
      72              :     }
      73              : 
      74           15 :     int edge_idx = bc_inlet_edge_to_index(config->edge);
      75           15 :     const bc_inlet_edge_loop_t* loop = &bc_inlet_edge_loops[edge_idx];
      76              : 
      77           15 :     if (loop->is_z_face) {
      78              :         /* Z-face inlet (FRONT or BACK): loop over the full xy-plane */
      79            0 :         if (nz <= 1 || !w) {
      80            0 :             return CFD_ERROR_INVALID;
      81              :         }
      82            0 :         size_t z_plane = (config->edge == BC_EDGE_FRONT)
      83            0 :                          ? (nz - 1) * stride_z
      84            0 :                          : 0;
      85            0 :         double w_val = bc_inlet_compute_w(config);
      86              :         /* Apply time modulation to w as well */
      87            0 :         double modulator = bc_time_get_modulator(&config->time_config,
      88            0 :                                                   time_ctx->time, time_ctx->dt);
      89            0 :         w_val *= modulator;
      90              : 
      91              :         /* Velocity is uniform across the z-face — compute once. */
      92            0 :         double u_val, v_val;
      93            0 :         bc_inlet_compute_velocity_time(config, 0.5,
      94            0 :                                         time_ctx->time, time_ctx->dt,
      95              :                                         &u_val, &v_val);
      96              : 
      97            0 :         for (size_t j = 0; j < ny; j++) {
      98            0 :             for (size_t i = 0; i < nx; i++) {
      99            0 :                 size_t idx = z_plane + IDX_2D(i, j, nx);
     100            0 :                 u[idx] = u_val;
     101            0 :                 v[idx] = v_val;
     102            0 :                 w[idx] = w_val;
     103              :             }
     104              :         }
     105              :     } else {
     106              :         /* X/Y-face inlet: loop over each z-plane */
     107           15 :         size_t count = loop->use_ny_for_count ? ny : nx;
     108           15 :         double pos_denom = (count > 1) ? (double)(count - 1) : 1.0;
     109              : 
     110           30 :         for (size_t k = 0; k < nz; k++) {
     111           15 :             size_t base = k * stride_z;
     112          255 :             for (size_t i = 0; i < count; i++) {
     113          240 :                 double position = (count > 1) ? (double)i / pos_denom : 0.5;
     114          240 :                 double u_val, v_val;
     115          240 :                 bc_inlet_compute_velocity_time(config, position,
     116          240 :                                                 time_ctx->time, time_ctx->dt,
     117              :                                                 &u_val, &v_val);
     118              : 
     119          240 :                 size_t idx = base + loop->idx_fn(i, nx, ny);
     120          240 :                 u[idx] = u_val;
     121          240 :                 v[idx] = v_val;
     122          240 :                 if (w) {
     123            0 :                     w[idx] = 0.0;
     124              :                 }
     125              :             }
     126              :         }
     127              :     }
     128              : 
     129              :     return CFD_SUCCESS;
     130              : }
        

Generated by: LCOV version 2.0-1