Line data Source code
1 : /**
2 : * Inlet Boundary Conditions - Scalar (CPU) Implementation
3 : *
4 : * Baseline scalar implementation of inlet velocity boundary conditions.
5 : * No SIMD, no OpenMP - pure C loops.
6 : *
7 : * Supports:
8 : * - Uniform velocity profile
9 : * - Parabolic profile (fully-developed flow)
10 : * - Custom user-defined profiles via callback
11 : * - Velocity specification by components, magnitude+direction, or mass flow rate
12 : * - 3D z-face inlets (FRONT/BACK edges)
13 : */
14 :
15 : #include "../boundary_conditions_inlet_common.h"
16 :
17 59 : cfd_status_t bc_apply_inlet_scalar_impl(double* u, double* v, double* w,
18 : size_t nx, size_t ny,
19 : size_t nz, size_t stride_z,
20 : const bc_inlet_config_t* config) {
21 59 : if (!u || !v || !config || nx < 3 || ny < 3) {
22 : return CFD_ERROR_INVALID;
23 : }
24 :
25 104 : if (!bc_inlet_is_valid_edge(config->edge)) {
26 : return CFD_ERROR_INVALID;
27 : }
28 :
29 45 : int edge_idx = bc_inlet_edge_to_index(config->edge);
30 45 : const bc_inlet_edge_loop_t* loop = &bc_inlet_edge_loops[edge_idx];
31 :
32 45 : if (loop->is_z_face) {
33 : /* Z-face inlet (FRONT or BACK): loop over the full xy-plane */
34 3 : if (nz <= 1 || !w) {
35 2 : return CFD_ERROR_INVALID;
36 : }
37 : /* FRONT = k=nz-1, BACK = k=0 */
38 2 : size_t z_plane = (config->edge == BC_EDGE_FRONT)
39 1 : ? (nz - 1) * stride_z
40 1 : : 0;
41 1 : double w_val = bc_inlet_compute_w(config);
42 :
43 : /* For z-face inlets, 1D profiles are not meaningful.
44 : * Velocity is uniform across the plane — compute once. */
45 1 : double u_val, v_val;
46 1 : bc_inlet_compute_velocity(config, 0.5, &u_val, &v_val);
47 :
48 6 : for (size_t j = 0; j < ny; j++) {
49 30 : for (size_t i = 0; i < nx; i++) {
50 25 : size_t idx = z_plane + IDX_2D(i, j, nx);
51 25 : u[idx] = u_val;
52 25 : v[idx] = v_val;
53 25 : w[idx] = w_val;
54 : }
55 : }
56 : } else {
57 : /* X/Y-face inlet: loop over each z-plane */
58 42 : size_t count = loop->use_ny_for_count ? ny : nx;
59 42 : double pos_denom = (count > 1) ? (double)(count - 1) : 1.0;
60 :
61 84 : for (size_t k = 0; k < nz; k++) {
62 42 : size_t base = k * stride_z;
63 578 : for (size_t i = 0; i < count; i++) {
64 536 : double position = (count > 1) ? (double)i / pos_denom : 0.5;
65 536 : double u_val, v_val;
66 536 : bc_inlet_compute_velocity(config, position, &u_val, &v_val);
67 :
68 536 : size_t idx = base + loop->idx_fn(i, nx, ny);
69 536 : u[idx] = u_val;
70 536 : v[idx] = v_val;
71 536 : if (w) {
72 0 : w[idx] = 0.0;
73 : }
74 : }
75 : }
76 : }
77 :
78 : return CFD_SUCCESS;
79 : }
|